summaryrefslogtreecommitdiffstats
path: root/js/src/jit/CacheIR.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/CacheIR.cpp')
-rw-r--r--js/src/jit/CacheIR.cpp79
1 files changed, 75 insertions, 4 deletions
diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp
index d184ea40c..f1061af70 100644
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -10,7 +10,8 @@
#include "jit/IonCaches.h"
#include "jsobjinlines.h"
-#include "vm/NativeObject-inl.h"
+
+#include "vm/UnboxedObject-inl.h"
using namespace js;
using namespace js::jit;
@@ -59,6 +60,10 @@ GetPropIRGenerator::tryAttachStub(Maybe<CacheIRWriter>& writer)
return false;
if (!emitted_ && !tryAttachNative(*writer, obj, objId))
return false;
+ if (!emitted_ && !tryAttachUnboxed(*writer, obj, objId))
+ return false;
+ if (!emitted_ && !tryAttachUnboxedExpando(*writer, obj, objId))
+ return false;
if (!emitted_ && !tryAttachTypedObject(*writer, obj, objId))
return false;
if (!emitted_ && !tryAttachModuleNamespace(*writer, obj, objId))
@@ -158,9 +163,19 @@ GeneratePrototypeGuards(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
}
static void
-TestMatchingReceiver(CacheIRWriter& writer, JSObject* obj, Shape* shape, ObjOperandId objId)
+TestMatchingReceiver(CacheIRWriter& writer, JSObject* obj, Shape* shape, ObjOperandId objId,
+ Maybe<ObjOperandId>* expandoId)
{
- if (obj->is<TypedObject>()) {
+ if (obj->is<UnboxedPlainObject>()) {
+ writer.guardGroup(objId, obj->group());
+
+ if (UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando()) {
+ expandoId->emplace(writer.guardAndLoadUnboxedExpando(objId));
+ writer.guardShape(expandoId->ref(), expando->lastProperty());
+ } else {
+ writer.guardNoUnboxedExpando(objId);
+ }
+ } else if (obj->is<UnboxedArrayObject>() || obj->is<TypedObject>()) {
writer.guardGroup(objId, obj->group());
} else {
Shape* shape = obj->maybeShape();
@@ -173,7 +188,8 @@ static void
EmitReadSlotResult(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
Shape* shape, ObjOperandId objId)
{
- TestMatchingReceiver(writer, obj, shape, objId);
+ Maybe<ObjOperandId> expandoId;
+ TestMatchingReceiver(writer, obj, shape, objId, &expandoId);
ObjOperandId holderId;
if (obj != holder) {
@@ -196,6 +212,9 @@ EmitReadSlotResult(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
lastObjId = protoId;
}
}
+ } else if (obj->is<UnboxedPlainObject>()) {
+ holder = obj->as<UnboxedPlainObject>().maybeExpando();
+ holderId = *expandoId;
} else {
holderId = objId;
}
@@ -247,6 +266,51 @@ GetPropIRGenerator::tryAttachNative(CacheIRWriter& writer, HandleObject obj, Obj
}
bool
+GetPropIRGenerator::tryAttachUnboxed(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId)
+{
+ MOZ_ASSERT(!emitted_);
+
+ if (!obj->is<UnboxedPlainObject>())
+ return true;
+
+ const UnboxedLayout::Property* property = obj->as<UnboxedPlainObject>().layout().lookup(name_);
+ if (!property)
+ return true;
+
+ if (!cx_->runtime()->jitSupportsFloatingPoint)
+ return true;
+
+ writer.guardGroup(objId, obj->group());
+ writer.loadUnboxedPropertyResult(objId, property->type,
+ UnboxedPlainObject::offsetOfData() + property->offset);
+ emitted_ = true;
+ preliminaryObjectAction_ = PreliminaryObjectAction::Unlink;
+ return true;
+}
+
+bool
+GetPropIRGenerator::tryAttachUnboxedExpando(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId)
+{
+ MOZ_ASSERT(!emitted_);
+
+ if (!obj->is<UnboxedPlainObject>())
+ return true;
+
+ UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando();
+ if (!expando)
+ return true;
+
+ Shape* shape = expando->lookup(cx_, NameToId(name_));
+ if (!shape || !shape->hasDefaultGetter() || !shape->hasSlot())
+ return true;
+
+ emitted_ = true;
+
+ EmitReadSlotResult(writer, obj, obj, shape, objId);
+ return true;
+}
+
+bool
GetPropIRGenerator::tryAttachTypedObject(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId)
{
MOZ_ASSERT(!emitted_);
@@ -304,6 +368,13 @@ GetPropIRGenerator::tryAttachObjectLength(CacheIRWriter& writer, HandleObject ob
return true;
}
+ if (obj->is<UnboxedArrayObject>()) {
+ writer.guardClass(objId, GuardClassKind::UnboxedArray);
+ writer.loadUnboxedArrayLengthResult(objId);
+ emitted_ = true;
+ return true;
+ }
+
if (obj->is<ArgumentsObject>() && !obj->as<ArgumentsObject>().hasOverriddenLength()) {
if (obj->is<MappedArgumentsObject>()) {
writer.guardClass(objId, GuardClassKind::MappedArguments);