diff options
Diffstat (limited to 'js/src/jit/CacheIR.cpp')
-rw-r--r-- | js/src/jit/CacheIR.cpp | 79 |
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); |