summaryrefslogtreecommitdiffstats
path: root/js
diff options
context:
space:
mode:
Diffstat (limited to 'js')
-rw-r--r--js/src/jit/BaselineCacheIR.cpp52
-rw-r--r--js/src/jit/BaselineIC.cpp114
-rw-r--r--js/src/jit/BaselineInspector.cpp46
-rw-r--r--js/src/jit/CacheIR.cpp72
-rw-r--r--js/src/jit/CacheIR.h20
-rw-r--r--js/src/jit/IonCaches.cpp262
-rw-r--r--js/src/jit/IonCaches.h12
-rw-r--r--js/src/jit/MacroAssembler.cpp264
-rw-r--r--js/src/jit/MacroAssembler.h14
-rw-r--r--js/src/vm/UnboxedObject.cpp201
10 files changed, 9 insertions, 1048 deletions
diff --git a/js/src/jit/BaselineCacheIR.cpp b/js/src/jit/BaselineCacheIR.cpp
index 7fb586811..67c80473b 100644
--- a/js/src/jit/BaselineCacheIR.cpp
+++ b/js/src/jit/BaselineCacheIR.cpp
@@ -16,7 +16,7 @@ using namespace js;
using namespace js::jit;
// OperandLocation represents the location of an OperandId. The operand is
-// either in a register or on the stack, and is either boxed or unboxed.
+// either in a register or on the stack.
class OperandLocation
{
public:
@@ -815,36 +815,6 @@ BaselineCacheIRCompiler::emitGuardSpecificObject()
}
bool
-BaselineCacheIRCompiler::emitGuardNoUnboxedExpando()
-{
- Register obj = allocator.useRegister(masm, reader.objOperandId());
-
- FailurePath* failure;
- if (!addFailurePath(&failure))
- return false;
-
- Address expandoAddr(obj, UnboxedPlainObject::offsetOfExpando());
- masm.branchPtr(Assembler::NotEqual, expandoAddr, ImmWord(0), failure->label());
- return true;
-}
-
-bool
-BaselineCacheIRCompiler::emitGuardAndLoadUnboxedExpando()
-{
- Register obj = allocator.useRegister(masm, reader.objOperandId());
- Register output = allocator.defineRegister(masm, reader.objOperandId());
-
- FailurePath* failure;
- if (!addFailurePath(&failure))
- return false;
-
- Address expandoAddr(obj, UnboxedPlainObject::offsetOfExpando());
- masm.loadPtr(expandoAddr, output);
- masm.branchTestPtr(Assembler::Zero, output, output, failure->label());
- return true;
-}
-
-bool
BaselineCacheIRCompiler::emitLoadFixedSlotResult()
{
Register obj = allocator.useRegister(masm, reader.objOperandId());
@@ -871,26 +841,6 @@ BaselineCacheIRCompiler::emitLoadDynamicSlotResult()
}
bool
-BaselineCacheIRCompiler::emitLoadUnboxedPropertyResult()
-{
- Register obj = allocator.useRegister(masm, reader.objOperandId());
- AutoScratchRegister scratch(allocator, masm);
-
- JSValueType fieldType = reader.valueType();
-
- Address fieldOffset(stubAddress(reader.stubOffset()));
- masm.load32(fieldOffset, scratch);
- masm.loadUnboxedProperty(BaseIndex(obj, scratch, TimesOne), fieldType, R0);
-
- if (fieldType == JSVAL_TYPE_OBJECT)
- emitEnterTypeMonitorIC();
- else
- emitReturnFromIC();
-
- return true;
-}
-
-bool
BaselineCacheIRCompiler::emitGuardNoDetachedTypedObjects()
{
FailurePath* failure;
diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp
index 64cdf01a6..ba855dac9 100644
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -1920,13 +1920,6 @@ ICGetElemNativeCompiler<T>::generateStubCode(MacroAssembler& masm)
if (popR1)
masm.addToStackPtr(ImmWord(sizeof(size_t)));
- } else if (acctype_ == ICGetElemNativeStub::UnboxedProperty) {
- masm.load32(Address(ICStubReg, ICGetElemNativeSlotStub<T>::offsetOfOffset()),
- scratchReg);
- masm.loadUnboxedProperty(BaseIndex(objReg, scratchReg, TimesOne), unboxedType_,
- TypedOrValueRegister(R0));
- if (popR1)
- masm.addToStackPtr(ImmWord(sizeof(size_t)));
} else {
MOZ_ASSERT(acctype_ == ICGetElemNativeStub::NativeGetter ||
acctype_ == ICGetElemNativeStub::ScriptedGetter);
@@ -4293,40 +4286,6 @@ TryAttachSetAccessorPropStub(JSContext* cx, HandleScript script, jsbytecode* pc,
}
static bool
-TryAttachUnboxedSetPropStub(JSContext* cx, HandleScript script,
- ICSetProp_Fallback* stub, HandleId id,
- HandleObject obj, HandleValue rhs, bool* attached)
-{
- MOZ_ASSERT(!*attached);
-
- if (!cx->runtime()->jitSupportsFloatingPoint)
- return true;
-
- if (!obj->is<UnboxedPlainObject>())
- return true;
-
- const UnboxedLayout::Property* property = obj->as<UnboxedPlainObject>().layout().lookup(id);
- if (!property)
- return true;
-
- ICSetProp_Unboxed::Compiler compiler(cx, obj->group(),
- property->offset + UnboxedPlainObject::offsetOfData(),
- property->type);
- ICUpdatedStub* newStub = compiler.getStub(compiler.getStubSpace(script));
- if (!newStub)
- return false;
- if (compiler.needsUpdateStubs() && !newStub->addUpdateStubForValue(cx, script, obj, id, rhs))
- return false;
-
- stub->addNewStub(newStub);
-
- StripPreliminaryObjectStubs(cx, stub);
-
- *attached = true;
- return true;
-}
-
-static bool
TryAttachTypedObjectSetPropStub(JSContext* cx, HandleScript script,
ICSetProp_Fallback* stub, HandleId id,
HandleObject obj, HandleValue rhs, bool* attached)
@@ -4487,15 +4446,6 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_
if (!attached &&
lhs.isObject() &&
- !TryAttachUnboxedSetPropStub(cx, script, stub, id, obj, rhs, &attached))
- {
- return false;
- }
- if (attached)
- return true;
-
- if (!attached &&
- lhs.isObject() &&
!TryAttachTypedObjectSetPropStub(cx, script, stub, id, obj, rhs, &attached))
{
return false;
@@ -4829,70 +4779,6 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler& masm)
}
bool
-ICSetProp_Unboxed::Compiler::generateStubCode(MacroAssembler& masm)
-{
- MOZ_ASSERT(engine_ == Engine::Baseline);
-
- Label failure;
-
- // Guard input is an object.
- masm.branchTestObject(Assembler::NotEqual, R0, &failure);
-
- AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
- Register scratch = regs.takeAny();
-
- // Unbox and group guard.
- Register object = masm.extractObject(R0, ExtractTemp0);
- masm.loadPtr(Address(ICStubReg, ICSetProp_Unboxed::offsetOfGroup()), scratch);
- masm.branchPtr(Assembler::NotEqual, Address(object, JSObject::offsetOfGroup()), scratch,
- &failure);
-
- if (needsUpdateStubs()) {
- // Stow both R0 and R1 (object and value).
- EmitStowICValues(masm, 2);
-
- // Move RHS into R0 for TypeUpdate check.
- masm.moveValue(R1, R0);
-
- // Call the type update stub.
- if (!callTypeUpdateIC(masm, sizeof(Value)))
- return false;
-
- // Unstow R0 and R1 (object and key)
- EmitUnstowICValues(masm, 2);
-
- // The TypeUpdate IC may have smashed object. Rederive it.
- masm.unboxObject(R0, object);
-
- // Trigger post barriers here on the values being written. Fields which
- // objects can be written to also need update stubs.
- LiveGeneralRegisterSet saveRegs;
- saveRegs.add(R0);
- saveRegs.add(R1);
- saveRegs.addUnchecked(object);
- saveRegs.add(ICStubReg);
- emitPostWriteBarrierSlot(masm, object, R1, scratch, saveRegs);
- }
-
- // Compute the address being written to.
- masm.load32(Address(ICStubReg, ICSetProp_Unboxed::offsetOfFieldOffset()), scratch);
- BaseIndex address(object, scratch, TimesOne);
-
- EmitUnboxedPreBarrierForBaseline(masm, address, fieldType_);
- masm.storeUnboxedProperty(address, fieldType_,
- ConstantOrRegister(TypedOrValueRegister(R1)), &failure);
-
- // The RHS has to be in R0.
- masm.moveValue(R1, R0);
-
- EmitReturnFromIC(masm);
-
- masm.bind(&failure);
- EmitStubGuardFailure(masm);
- return true;
-}
-
-bool
ICSetProp_TypedObject::Compiler::generateStubCode(MacroAssembler& masm)
{
MOZ_ASSERT(engine_ == Engine::Baseline);
diff --git a/js/src/jit/BaselineInspector.cpp b/js/src/jit/BaselineInspector.cpp
index bcb527516..3b852debf 100644
--- a/js/src/jit/BaselineInspector.cpp
+++ b/js/src/jit/BaselineInspector.cpp
@@ -104,19 +104,11 @@ AddReceiver(const ReceiverGuard& receiver,
static bool
GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* receiver)
{
- // We match either:
+ // We match:
//
// GuardIsObject 0
// GuardShape 0
// LoadFixedSlotResult 0 or LoadDynamicSlotResult 0
- //
- // or
- //
- // GuardIsObject 0
- // GuardGroup 0
- // 1: GuardAndLoadUnboxedExpando 0
- // GuardShape 1
- // LoadFixedSlotResult 1 or LoadDynamicSlotResult 1
*receiver = ReceiverGuard();
CacheIRReader reader(stub->stubInfo());
@@ -125,14 +117,6 @@ GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* re
if (!reader.matchOp(CacheOp::GuardIsObject, objId))
return false;
- if (reader.matchOp(CacheOp::GuardGroup, objId)) {
- receiver->group = stub->stubInfo()->getStubField<ObjectGroup*>(stub, reader.stubOffset());
-
- if (!reader.matchOp(CacheOp::GuardAndLoadUnboxedExpando, objId))
- return false;
- objId = reader.objOperandId();
- }
-
if (reader.matchOp(CacheOp::GuardShape, objId)) {
receiver->shape = stub->stubInfo()->getStubField<Shape*>(stub, reader.stubOffset());
return reader.matchOpEither(CacheOp::LoadFixedSlotResult, CacheOp::LoadDynamicSlotResult);
@@ -141,29 +125,6 @@ GetCacheIRReceiverForNativeReadSlot(ICCacheIR_Monitored* stub, ReceiverGuard* re
return false;
}
-static bool
-GetCacheIRReceiverForUnboxedProperty(ICCacheIR_Monitored* stub, ReceiverGuard* receiver)
-{
- // We match:
- //
- // GuardIsObject 0
- // GuardGroup 0
- // LoadUnboxedPropertyResult 0 ..
-
- *receiver = ReceiverGuard();
- CacheIRReader reader(stub->stubInfo());
-
- ObjOperandId objId = ObjOperandId(0);
- if (!reader.matchOp(CacheOp::GuardIsObject, objId))
- return false;
-
- if (!reader.matchOp(CacheOp::GuardGroup, objId))
- return false;
- receiver->group = stub->stubInfo()->getStubField<ObjectGroup*>(stub, reader.stubOffset());
-
- return reader.matchOp(CacheOp::LoadUnboxedPropertyResult, objId);
-}
-
bool
BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receivers)
{
@@ -182,8 +143,7 @@ BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receiv
while (stub->next()) {
ReceiverGuard receiver;
if (stub->isCacheIR_Monitored()) {
- if (!GetCacheIRReceiverForNativeReadSlot(stub->toCacheIR_Monitored(), &receiver) &&
- !GetCacheIRReceiverForUnboxedProperty(stub->toCacheIR_Monitored(), &receiver))
+ if (!GetCacheIRReceiverForNativeReadSlot(stub->toCacheIR_Monitored(), &receiver))
{
receivers.clear();
return true;
@@ -191,8 +151,6 @@ BaselineInspector::maybeInfoForPropertyOp(jsbytecode* pc, ReceiverVector& receiv
} else if (stub->isSetProp_Native()) {
receiver = ReceiverGuard(stub->toSetProp_Native()->group(),
stub->toSetProp_Native()->shape());
- } else if (stub->isSetProp_Unboxed()) {
- receiver = ReceiverGuard(stub->toSetProp_Unboxed()->group(), nullptr);
} else {
receivers.clear();
return true;
diff --git a/js/src/jit/CacheIR.cpp b/js/src/jit/CacheIR.cpp
index 6822a70af..d184ea40c 100644
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -10,8 +10,7 @@
#include "jit/IonCaches.h"
#include "jsobjinlines.h"
-
-#include "vm/UnboxedObject-inl.h"
+#include "vm/NativeObject-inl.h"
using namespace js;
using namespace js::jit;
@@ -60,10 +59,6 @@ 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))
@@ -163,19 +158,9 @@ GeneratePrototypeGuards(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
}
static void
-TestMatchingReceiver(CacheIRWriter& writer, JSObject* obj, Shape* shape, ObjOperandId objId,
- Maybe<ObjOperandId>* expandoId)
+TestMatchingReceiver(CacheIRWriter& writer, JSObject* obj, Shape* shape, ObjOperandId objId)
{
- 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<TypedObject>()) {
+ if (obj->is<TypedObject>()) {
writer.guardGroup(objId, obj->group());
} else {
Shape* shape = obj->maybeShape();
@@ -188,8 +173,7 @@ static void
EmitReadSlotResult(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
Shape* shape, ObjOperandId objId)
{
- Maybe<ObjOperandId> expandoId;
- TestMatchingReceiver(writer, obj, shape, objId, &expandoId);
+ TestMatchingReceiver(writer, obj, shape, objId);
ObjOperandId holderId;
if (obj != holder) {
@@ -212,9 +196,6 @@ EmitReadSlotResult(CacheIRWriter& writer, JSObject* obj, JSObject* holder,
lastObjId = protoId;
}
}
- } else if (obj->is<UnboxedPlainObject>()) {
- holder = obj->as<UnboxedPlainObject>().maybeExpando();
- holderId = *expandoId;
} else {
holderId = objId;
}
@@ -266,51 +247,6 @@ 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_);
diff --git a/js/src/jit/CacheIR.h b/js/src/jit/CacheIR.h
index 4fd8575f0..ae55cfebb 100644
--- a/js/src/jit/CacheIR.h
+++ b/js/src/jit/CacheIR.h
@@ -87,13 +87,10 @@ class ObjOperandId : public OperandId
_(GuardClass) \
_(GuardSpecificObject) \
_(GuardNoDetachedTypedObjects) \
- _(GuardNoUnboxedExpando) \
- _(GuardAndLoadUnboxedExpando) \
_(LoadObject) \
_(LoadProto) \
_(LoadFixedSlotResult) \
_(LoadDynamicSlotResult) \
- _(LoadUnboxedPropertyResult) \
_(LoadTypedObjectResult) \
_(LoadInt32ArrayLengthResult) \
_(LoadArgumentsObjectLengthResult) \
@@ -274,15 +271,6 @@ class MOZ_RAII CacheIRWriter
void guardNoDetachedTypedObjects() {
writeOp(CacheOp::GuardNoDetachedTypedObjects);
}
- void guardNoUnboxedExpando(ObjOperandId obj) {
- writeOpWithOperandId(CacheOp::GuardNoUnboxedExpando, obj);
- }
- ObjOperandId guardAndLoadUnboxedExpando(ObjOperandId obj) {
- ObjOperandId res(nextOperandId_++);
- writeOpWithOperandId(CacheOp::GuardAndLoadUnboxedExpando, obj);
- writeOperandId(res);
- return res;
- }
ObjOperandId loadObject(JSObject* obj) {
ObjOperandId res(nextOperandId_++);
@@ -308,11 +296,6 @@ class MOZ_RAII CacheIRWriter
writeOpWithOperandId(CacheOp::LoadDynamicSlotResult, obj);
addStubWord(offset, StubField::GCType::NoGCThing);
}
- void loadUnboxedPropertyResult(ObjOperandId obj, JSValueType type, size_t offset) {
- writeOpWithOperandId(CacheOp::LoadUnboxedPropertyResult, obj);
- buffer_.writeByte(uint32_t(type));
- addStubWord(offset, StubField::GCType::NoGCThing);
- }
void loadTypedObjectResult(ObjOperandId obj, uint32_t offset, TypedThingLayout layout,
uint32_t typeDescr) {
MOZ_ASSERT(uint32_t(layout) <= UINT8_MAX);
@@ -406,9 +389,6 @@ class MOZ_RAII GetPropIRGenerator
PreliminaryObjectAction preliminaryObjectAction_;
MOZ_MUST_USE bool tryAttachNative(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
- MOZ_MUST_USE bool tryAttachUnboxed(CacheIRWriter& writer, HandleObject obj, ObjOperandId objId);
- MOZ_MUST_USE bool tryAttachUnboxedExpando(CacheIRWriter& writer, HandleObject obj,
- ObjOperandId objId);
MOZ_MUST_USE bool tryAttachTypedObject(CacheIRWriter& writer, HandleObject obj,
ObjOperandId objId);
MOZ_MUST_USE bool tryAttachObjectLength(CacheIRWriter& writer, HandleObject obj,
diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp
index 81cf9d9bb..1ef25cbd5 100644
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -867,30 +867,6 @@ GenerateReadSlot(JSContext* cx, IonScript* ion, MacroAssembler& masm,
attacher.jumpNextStub(masm);
}
-static void
-GenerateReadUnboxed(JSContext* cx, IonScript* ion, MacroAssembler& masm,
- IonCache::StubAttacher& attacher, JSObject* obj,
- const UnboxedLayout::Property* property,
- Register object, TypedOrValueRegister output,
- Label* failures = nullptr)
-{
- // Guard on the group of the object.
- attacher.branchNextStubOrLabel(masm, Assembler::NotEqual,
- Address(object, JSObject::offsetOfGroup()),
- ImmGCPtr(obj->group()), failures);
-
- Address address(object, UnboxedPlainObject::offsetOfData() + property->offset);
-
- masm.loadUnboxedProperty(address, property->type, output);
-
- attacher.jumpRejoin(masm);
-
- if (failures) {
- masm.bind(failures);
- attacher.jumpNextStub(masm);
- }
-}
-
static bool
EmitGetterCall(JSContext* cx, MacroAssembler& masm,
IonCache::StubAttacher& attacher, JSObject* obj,
@@ -1498,67 +1474,6 @@ GetPropertyIC::tryAttachNative(JSContext* cx, HandleScript outerScript, IonScrip
}
bool
-GetPropertyIC::tryAttachUnboxed(JSContext* cx, HandleScript outerScript, IonScript* ion,
- HandleObject obj, HandleId id, void* returnAddr, bool* emitted)
-{
- MOZ_ASSERT(canAttachStub());
- MOZ_ASSERT(!*emitted);
- MOZ_ASSERT(outerScript->ionScript() == ion);
-
- if (!obj->is<UnboxedPlainObject>())
- return true;
- const UnboxedLayout::Property* property = obj->as<UnboxedPlainObject>().layout().lookup(id);
- if (!property)
- return true;
-
- *emitted = true;
-
- MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
-
- Label failures;
- emitIdGuard(masm, id, &failures);
- Label* maybeFailures = failures.used() ? &failures : nullptr;
-
- StubAttacher attacher(*this);
- GenerateReadUnboxed(cx, ion, masm, attacher, obj, property, object(), output(), maybeFailures);
- return linkAndAttachStub(cx, masm, attacher, ion, "read unboxed",
- JS::TrackedOutcome::ICGetPropStub_UnboxedRead);
-}
-
-bool
-GetPropertyIC::tryAttachUnboxedExpando(JSContext* cx, HandleScript outerScript, IonScript* ion,
- HandleObject obj, HandleId id, void* returnAddr, bool* emitted)
-{
- MOZ_ASSERT(canAttachStub());
- MOZ_ASSERT(!*emitted);
- MOZ_ASSERT(outerScript->ionScript() == ion);
-
- if (!obj->is<UnboxedPlainObject>())
- return true;
- Rooted<UnboxedExpandoObject*> expando(cx, obj->as<UnboxedPlainObject>().maybeExpando());
- if (!expando)
- return true;
-
- Shape* shape = expando->lookup(cx, id);
- if (!shape || !shape->hasDefaultGetter() || !shape->hasSlot())
- return true;
-
- *emitted = true;
-
- MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
-
- Label failures;
- emitIdGuard(masm, id, &failures);
- Label* maybeFailures = failures.used() ? &failures : nullptr;
-
- StubAttacher attacher(*this);
- GenerateReadSlot(cx, ion, masm, attacher, DontCheckTDZ, obj, obj,
- shape, object(), output(), maybeFailures);
- return linkAndAttachStub(cx, masm, attacher, ion, "read unboxed expando",
- JS::TrackedOutcome::ICGetPropStub_UnboxedReadExpando);
-}
-
-bool
GetPropertyIC::tryAttachTypedArrayLength(JSContext* cx, HandleScript outerScript, IonScript* ion,
HandleObject obj, HandleId id, bool* emitted)
{
@@ -2127,12 +2042,6 @@ GetPropertyIC::tryAttachStub(JSContext* cx, HandleScript outerScript, IonScript*
if (!*emitted && !tryAttachNative(cx, outerScript, ion, obj, id, returnAddr, emitted))
return false;
- if (!*emitted && !tryAttachUnboxed(cx, outerScript, ion, obj, id, returnAddr, emitted))
- return false;
-
- if (!*emitted && !tryAttachUnboxedExpando(cx, outerScript, ion, obj, id, returnAddr, emitted))
- return false;
-
if (!*emitted && !tryAttachTypedArrayLength(cx, outerScript, ion, obj, id, emitted))
return false;
}
@@ -3298,141 +3207,6 @@ CanAttachNativeSetProp(JSContext* cx, HandleObject obj, HandleId id, const Const
return SetPropertyIC::CanAttachNone;
}
-static void
-GenerateSetUnboxed(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& attacher,
- JSObject* obj, jsid id, uint32_t unboxedOffset, JSValueType unboxedType,
- Register object, Register tempReg, const ConstantOrRegister& value,
- bool checkTypeset, Label* failures)
-{
- // Guard on the type of the object.
- masm.branchPtr(Assembler::NotEqual,
- Address(object, JSObject::offsetOfGroup()),
- ImmGCPtr(obj->group()), failures);
-
- if (checkTypeset)
- CheckTypeSetForWrite(masm, obj, id, tempReg, value, failures);
-
- Address address(object, UnboxedPlainObject::offsetOfData() + unboxedOffset);
-
- if (cx->zone()->needsIncrementalBarrier()) {
- if (unboxedType == JSVAL_TYPE_OBJECT)
- masm.callPreBarrier(address, MIRType::Object);
- else if (unboxedType == JSVAL_TYPE_STRING)
- masm.callPreBarrier(address, MIRType::String);
- else
- MOZ_ASSERT(!UnboxedTypeNeedsPreBarrier(unboxedType));
- }
-
- masm.storeUnboxedProperty(address, unboxedType, value, failures);
-
- attacher.jumpRejoin(masm);
-
- masm.bind(failures);
- attacher.jumpNextStub(masm);
-}
-
-static bool
-CanAttachSetUnboxed(JSContext* cx, HandleObject obj, HandleId id, const ConstantOrRegister& val,
- bool needsTypeBarrier, bool* checkTypeset,
- uint32_t* unboxedOffset, JSValueType* unboxedType)
-{
- if (!obj->is<UnboxedPlainObject>())
- return false;
-
- const UnboxedLayout::Property* property = obj->as<UnboxedPlainObject>().layout().lookup(id);
- if (property) {
- *checkTypeset = false;
- if (needsTypeBarrier && !CanInlineSetPropTypeCheck(obj, id, val, checkTypeset))
- return false;
- *unboxedOffset = property->offset;
- *unboxedType = property->type;
- return true;
- }
-
- return false;
-}
-
-static bool
-CanAttachSetUnboxedExpando(JSContext* cx, HandleObject obj, HandleId id,
- const ConstantOrRegister& val,
- bool needsTypeBarrier, bool* checkTypeset, Shape** pshape)
-{
- if (!obj->is<UnboxedPlainObject>())
- return false;
-
- Rooted<UnboxedExpandoObject*> expando(cx, obj->as<UnboxedPlainObject>().maybeExpando());
- if (!expando)
- return false;
-
- Shape* shape = expando->lookupPure(id);
- if (!shape || !shape->hasDefaultSetter() || !shape->hasSlot() || !shape->writable())
- return false;
-
- *checkTypeset = false;
- if (needsTypeBarrier && !CanInlineSetPropTypeCheck(obj, id, val, checkTypeset))
- return false;
-
- *pshape = shape;
- return true;
-}
-
-static bool
-CanAttachAddUnboxedExpando(JSContext* cx, HandleObject obj, HandleShape oldShape,
- HandleId id, const ConstantOrRegister& val,
- bool needsTypeBarrier, bool* checkTypeset)
-{
- if (!obj->is<UnboxedPlainObject>())
- return false;
-
- Rooted<UnboxedExpandoObject*> expando(cx, obj->as<UnboxedPlainObject>().maybeExpando());
- if (!expando || expando->inDictionaryMode())
- return false;
-
- Shape* newShape = expando->lastProperty();
- if (newShape->isEmptyShape() || newShape->propid() != id || newShape->previous() != oldShape)
- return false;
-
- MOZ_ASSERT(newShape->hasDefaultSetter() && newShape->hasSlot() && newShape->writable());
-
- if (PrototypeChainShadowsPropertyAdd(cx, obj, id))
- return false;
-
- *checkTypeset = false;
- if (needsTypeBarrier && !CanInlineSetPropTypeCheck(obj, id, val, checkTypeset))
- return false;
-
- return true;
-}
-
-bool
-SetPropertyIC::tryAttachUnboxed(JSContext* cx, HandleScript outerScript, IonScript* ion,
- HandleObject obj, HandleId id, bool* emitted)
-{
- MOZ_ASSERT(!*emitted);
-
- bool checkTypeset = false;
- uint32_t unboxedOffset;
- JSValueType unboxedType;
- if (!CanAttachSetUnboxed(cx, obj, id, value(), needsTypeBarrier(), &checkTypeset,
- &unboxedOffset, &unboxedType))
- {
- return true;
- }
-
- *emitted = true;
-
- MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_);
- StubAttacher attacher(*this);
-
- Label failures;
- emitIdGuard(masm, id, &failures);
-
- GenerateSetUnboxed(cx, masm, attacher, obj, id, unboxedOffset, unboxedType,
- object(), temp(), value(), checkTypeset, &failures);
- return linkAndAttachStub(cx, masm, attacher, ion, "set_unboxed",
- JS::TrackedOutcome::ICSetPropStub_SetUnboxed);
-}
-
bool
SetPropertyIC::tryAttachProxy(JSContext* cx, HandleScript outerScript, IonScript* ion,
HandleObject obj, HandleId id, bool* emitted)
@@ -3514,26 +3288,6 @@ SetPropertyIC::tryAttachNative(JSContext* cx, HandleScript outerScript, IonScrip
}
bool
-SetPropertyIC::tryAttachUnboxedExpando(JSContext* cx, HandleScript outerScript, IonScript* ion,
- HandleObject obj, HandleId id, bool* emitted)
-{
- MOZ_ASSERT(!*emitted);
-
- RootedShape shape(cx);
- bool checkTypeset = false;
- if (!CanAttachSetUnboxedExpando(cx, obj, id, value(), needsTypeBarrier(),
- &checkTypeset, shape.address()))
- {
- return true;
- }
-
- if (!attachSetSlot(cx, outerScript, ion, obj, shape, checkTypeset))
- return false;
- *emitted = true;
- return true;
-}
-
-bool
SetPropertyIC::tryAttachStub(JSContext* cx, HandleScript outerScript, IonScript* ion,
HandleObject obj, HandleValue idval, HandleValue value,
MutableHandleId id, bool* emitted, bool* tryNativeAddSlot)
@@ -3558,12 +3312,6 @@ SetPropertyIC::tryAttachStub(JSContext* cx, HandleScript outerScript, IonScript*
if (!*emitted && !tryAttachNative(cx, outerScript, ion, obj, id, emitted, tryNativeAddSlot))
return false;
-
- if (!*emitted && !tryAttachUnboxed(cx, outerScript, ion, obj, id, emitted))
- return false;
-
- if (!*emitted && !tryAttachUnboxedExpando(cx, outerScript, ion, obj, id, emitted))
- return false;
}
if (idval.isInt32()) {
@@ -3615,16 +3363,6 @@ SetPropertyIC::tryAttachAddSlot(JSContext* cx, HandleScript outerScript, IonScri
return true;
}
- checkTypeset = false;
- if (CanAttachAddUnboxedExpando(cx, obj, oldShape, id, value(), needsTypeBarrier(),
- &checkTypeset))
- {
- if (!attachAddSlot(cx, outerScript, ion, obj, id, oldShape, oldGroup, checkTypeset))
- return false;
- *emitted = true;
- return true;
- }
-
return true;
}
diff --git a/js/src/jit/IonCaches.h b/js/src/jit/IonCaches.h
index 173e06c6b..b00646538 100644
--- a/js/src/jit/IonCaches.h
+++ b/js/src/jit/IonCaches.h
@@ -529,18 +529,6 @@ class GetPropertyIC : public IonCache
HandleObject obj, HandleId id, void* returnAddr,
bool* emitted);
- MOZ_MUST_USE bool tryAttachUnboxed(JSContext* cx, HandleScript outerScript, IonScript* ion,
- HandleObject obj, HandleId id, void* returnAddr,
- bool* emitted);
-
- MOZ_MUST_USE bool tryAttachUnboxedExpando(JSContext* cx, HandleScript outerScript,
- IonScript* ion, HandleObject obj, HandleId id,
- void* returnAddr, bool* emitted);
-
- MOZ_MUST_USE bool tryAttachUnboxedArrayLength(JSContext* cx, HandleScript outerScript,
- IonScript* ion, HandleObject obj, HandleId id,
- void* returnAddr, bool* emitted);
-
MOZ_MUST_USE bool tryAttachTypedArrayLength(JSContext* cx, HandleScript outerScript,
IonScript* ion, HandleObject obj, HandleId id,
bool* emitted);
diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp
index e50f68722..bc04e85cf 100644
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -468,243 +468,6 @@ template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const A
template void MacroAssembler::loadFromTypedArray(Scalar::Type arrayType, const BaseIndex& src, const ValueOperand& dest,
bool allowDouble, Register temp, Label* fail);
-template <typename T>
-void
-MacroAssembler::loadUnboxedProperty(T address, JSValueType type, TypedOrValueRegister output)
-{
- switch (type) {
- case JSVAL_TYPE_INT32: {
- // Handle loading an int32 into a double reg.
- if (output.type() == MIRType::Double) {
- convertInt32ToDouble(address, output.typedReg().fpu());
- break;
- }
- MOZ_FALLTHROUGH;
- }
-
- case JSVAL_TYPE_BOOLEAN:
- case JSVAL_TYPE_STRING: {
- Register outReg;
- if (output.hasValue()) {
- outReg = output.valueReg().scratchReg();
- } else {
- MOZ_ASSERT(output.type() == MIRTypeFromValueType(type));
- outReg = output.typedReg().gpr();
- }
-
- switch (type) {
- case JSVAL_TYPE_BOOLEAN:
- load8ZeroExtend(address, outReg);
- break;
- case JSVAL_TYPE_INT32:
- load32(address, outReg);
- break;
- case JSVAL_TYPE_STRING:
- loadPtr(address, outReg);
- break;
- default:
- MOZ_CRASH();
- }
-
- if (output.hasValue())
- tagValue(type, outReg, output.valueReg());
- break;
- }
-
- case JSVAL_TYPE_OBJECT:
- if (output.hasValue()) {
- Register scratch = output.valueReg().scratchReg();
- loadPtr(address, scratch);
-
- Label notNull, done;
- branchPtr(Assembler::NotEqual, scratch, ImmWord(0), &notNull);
-
- moveValue(NullValue(), output.valueReg());
- jump(&done);
-
- bind(&notNull);
- tagValue(JSVAL_TYPE_OBJECT, scratch, output.valueReg());
-
- bind(&done);
- } else {
- // Reading null can't be possible here, as otherwise the result
- // would be a value (either because null has been read before or
- // because there is a barrier).
- Register reg = output.typedReg().gpr();
- loadPtr(address, reg);
-#ifdef DEBUG
- Label ok;
- branchTestPtr(Assembler::NonZero, reg, reg, &ok);
- assumeUnreachable("Null not possible");
- bind(&ok);
-#endif
- }
- break;
-
- case JSVAL_TYPE_DOUBLE:
- // Note: doubles in unboxed objects are not accessed through other
- // views and do not need canonicalization.
- if (output.hasValue())
- loadValue(address, output.valueReg());
- else
- loadDouble(address, output.typedReg().fpu());
- break;
-
- default:
- MOZ_CRASH();
- }
-}
-
-template void
-MacroAssembler::loadUnboxedProperty(Address address, JSValueType type,
- TypedOrValueRegister output);
-
-template void
-MacroAssembler::loadUnboxedProperty(BaseIndex address, JSValueType type,
- TypedOrValueRegister output);
-
-static void
-StoreUnboxedFailure(MacroAssembler& masm, Label* failure)
-{
- // Storing a value to an unboxed property is a fallible operation and
- // the caller must provide a failure label if a particular unboxed store
- // might fail. Sometimes, however, a store that cannot succeed (such as
- // storing a string to an int32 property) will be marked as infallible.
- // This can only happen if the code involved is unreachable.
- if (failure)
- masm.jump(failure);
- else
- masm.assumeUnreachable("Incompatible write to unboxed property");
-}
-
-template <typename T>
-void
-MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
- const ConstantOrRegister& value, Label* failure)
-{
- switch (type) {
- case JSVAL_TYPE_BOOLEAN:
- if (value.constant()) {
- if (value.value().isBoolean())
- store8(Imm32(value.value().toBoolean()), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else if (value.reg().hasTyped()) {
- if (value.reg().type() == MIRType::Boolean)
- store8(value.reg().typedReg().gpr(), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else {
- if (failure)
- branchTestBoolean(Assembler::NotEqual, value.reg().valueReg(), failure);
- storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ 1);
- }
- break;
-
- case JSVAL_TYPE_INT32:
- if (value.constant()) {
- if (value.value().isInt32())
- store32(Imm32(value.value().toInt32()), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else if (value.reg().hasTyped()) {
- if (value.reg().type() == MIRType::Int32)
- store32(value.reg().typedReg().gpr(), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else {
- if (failure)
- branchTestInt32(Assembler::NotEqual, value.reg().valueReg(), failure);
- storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ 4);
- }
- break;
-
- case JSVAL_TYPE_DOUBLE:
- if (value.constant()) {
- if (value.value().isNumber()) {
- loadConstantDouble(value.value().toNumber(), ScratchDoubleReg);
- storeDouble(ScratchDoubleReg, address);
- } else {
- StoreUnboxedFailure(*this, failure);
- }
- } else if (value.reg().hasTyped()) {
- if (value.reg().type() == MIRType::Int32) {
- convertInt32ToDouble(value.reg().typedReg().gpr(), ScratchDoubleReg);
- storeDouble(ScratchDoubleReg, address);
- } else if (value.reg().type() == MIRType::Double) {
- storeDouble(value.reg().typedReg().fpu(), address);
- } else {
- StoreUnboxedFailure(*this, failure);
- }
- } else {
- ValueOperand reg = value.reg().valueReg();
- Label notInt32, end;
- branchTestInt32(Assembler::NotEqual, reg, &notInt32);
- int32ValueToDouble(reg, ScratchDoubleReg);
- storeDouble(ScratchDoubleReg, address);
- jump(&end);
- bind(&notInt32);
- if (failure)
- branchTestDouble(Assembler::NotEqual, reg, failure);
- storeValue(reg, address);
- bind(&end);
- }
- break;
-
- case JSVAL_TYPE_OBJECT:
- if (value.constant()) {
- if (value.value().isObjectOrNull())
- storePtr(ImmGCPtr(value.value().toObjectOrNull()), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else if (value.reg().hasTyped()) {
- MOZ_ASSERT(value.reg().type() != MIRType::Null);
- if (value.reg().type() == MIRType::Object)
- storePtr(value.reg().typedReg().gpr(), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else {
- if (failure) {
- Label ok;
- branchTestNull(Assembler::Equal, value.reg().valueReg(), &ok);
- branchTestObject(Assembler::NotEqual, value.reg().valueReg(), failure);
- bind(&ok);
- }
- storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ sizeof(uintptr_t));
- }
- break;
-
- case JSVAL_TYPE_STRING:
- if (value.constant()) {
- if (value.value().isString())
- storePtr(ImmGCPtr(value.value().toString()), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else if (value.reg().hasTyped()) {
- if (value.reg().type() == MIRType::String)
- storePtr(value.reg().typedReg().gpr(), address);
- else
- StoreUnboxedFailure(*this, failure);
- } else {
- if (failure)
- branchTestString(Assembler::NotEqual, value.reg().valueReg(), failure);
- storeUnboxedPayload(value.reg().valueReg(), address, /* width = */ sizeof(uintptr_t));
- }
- break;
-
- default:
- MOZ_CRASH();
- }
-}
-
-template void
-MacroAssembler::storeUnboxedProperty(Address address, JSValueType type,
- const ConstantOrRegister& value, Label* failure);
-
-template void
-MacroAssembler::storeUnboxedProperty(BaseIndex address, JSValueType type,
- const ConstantOrRegister& value, Label* failure);
-
// Inlined version of gc::CheckAllocatorState that checks the bare essentials
// and bails for anything that cannot be handled with our jit allocators.
void
@@ -1252,10 +1015,6 @@ MacroAssembler::initGCThing(Register obj, Register temp, JSObject* templateObj,
nbytes = (nbytes < sizeof(uintptr_t)) ? 0 : nbytes - sizeof(uintptr_t);
offset += sizeof(uintptr_t);
}
- } else if (templateObj->is<UnboxedPlainObject>()) {
- storePtr(ImmWord(0), Address(obj, UnboxedPlainObject::offsetOfExpando()));
- if (initContents)
- initUnboxedObjectContents(obj, &templateObj->as<UnboxedPlainObject>());
} else {
MOZ_CRASH("Unknown object");
}
@@ -1277,29 +1036,6 @@ MacroAssembler::initGCThing(Register obj, Register temp, JSObject* templateObj,
}
void
-MacroAssembler::initUnboxedObjectContents(Register object, UnboxedPlainObject* templateObject)
-{
- const UnboxedLayout& layout = templateObject->layoutDontCheckGeneration();
-
- // Initialize reference fields of the object, per UnboxedPlainObject::create.
- if (const int32_t* list = layout.traceList()) {
- while (*list != -1) {
- storePtr(ImmGCPtr(GetJitContext()->runtime->names().empty),
- Address(object, UnboxedPlainObject::offsetOfData() + *list));
- list++;
- }
- list++;
- while (*list != -1) {
- storePtr(ImmWord(0),
- Address(object, UnboxedPlainObject::offsetOfData() + *list));
- list++;
- }
- // Unboxed objects don't have Values to initialize.
- MOZ_ASSERT(*(list + 1) == -1);
- }
-}
-
-void
MacroAssembler::compareStrings(JSOp op, Register left, Register right, Register result,
Label* fail)
{
diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h
index 6ee989463..d5cc95839 100644
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -36,7 +36,6 @@
#include "vm/ProxyObject.h"
#include "vm/Shape.h"
#include "vm/TypedArrayObject.h"
-#include "vm/UnboxedObject.h"
using mozilla::FloatingPoint;
@@ -1626,17 +1625,6 @@ class MacroAssembler : public MacroAssemblerSpecific
void storeToTypedFloatArray(Scalar::Type arrayType, FloatRegister value, const Address& dest,
unsigned numElems = 0);
- // Load a property from an UnboxedPlainObject.
- template <typename T>
- void loadUnboxedProperty(T address, JSValueType type, TypedOrValueRegister output);
-
- // Store a property to an UnboxedPlainObject, without triggering barriers.
- // If failure is null, the value definitely has a type suitable for storing
- // in the property.
- template <typename T>
- void storeUnboxedProperty(T address, JSValueType type,
- const ConstantOrRegister& value, Label* failure);
-
Register extractString(const Address& address, Register scratch) {
return extractObject(address, scratch);
}
@@ -1713,8 +1701,6 @@ class MacroAssembler : public MacroAssemblerSpecific
LiveRegisterSet liveRegs, Label* fail,
TypedArrayObject* templateObj, TypedArrayLength lengthKind);
- void initUnboxedObjectContents(Register object, UnboxedPlainObject* templateObject);
-
void newGCString(Register result, Register temp, Label* fail);
void newGCFatInlineString(Register result, Register temp, Label* fail);
diff --git a/js/src/vm/UnboxedObject.cpp b/js/src/vm/UnboxedObject.cpp
index 806a9db81..a96fb58a8 100644
--- a/js/src/vm/UnboxedObject.cpp
+++ b/js/src/vm/UnboxedObject.cpp
@@ -67,205 +67,8 @@ static const uintptr_t CLEAR_CONSTRUCTOR_CODE_TOKEN = 0x1;
/* static */ bool
UnboxedLayout::makeConstructorCode(JSContext* cx, HandleObjectGroup group)
{
- gc::AutoSuppressGC suppress(cx);
-
- using namespace jit;
-
- if (!cx->compartment()->ensureJitCompartmentExists(cx))
- return false;
-
- UnboxedLayout& layout = group->unboxedLayout();
- MOZ_ASSERT(!layout.constructorCode());
-
- UnboxedPlainObject* templateObject = UnboxedPlainObject::create(cx, group, TenuredObject);
- if (!templateObject)
- return false;
-
- JitContext jitContext(cx, nullptr);
-
- MacroAssembler masm;
-
- Register propertiesReg, newKindReg;
-#ifdef JS_CODEGEN_X86
- propertiesReg = eax;
- newKindReg = ecx;
- masm.loadPtr(Address(masm.getStackPointer(), sizeof(void*)), propertiesReg);
- masm.loadPtr(Address(masm.getStackPointer(), 2 * sizeof(void*)), newKindReg);
-#else
- propertiesReg = IntArgReg0;
- newKindReg = IntArgReg1;
-#endif
-
-#ifdef JS_CODEGEN_ARM64
- // ARM64 communicates stack address via sp, but uses a pseudo-sp for addressing.
- masm.initStackPtr();
-#endif
-
- MOZ_ASSERT(propertiesReg.volatile_());
- MOZ_ASSERT(newKindReg.volatile_());
-
- AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
- regs.take(propertiesReg);
- regs.take(newKindReg);
- Register object = regs.takeAny(), scratch1 = regs.takeAny(), scratch2 = regs.takeAny();
-
- LiveGeneralRegisterSet savedNonVolatileRegisters = SavedNonVolatileRegisters(regs);
- masm.PushRegsInMask(savedNonVolatileRegisters);
-
- // The scratch double register might be used by MacroAssembler methods.
- if (ScratchDoubleReg.volatile_())
- masm.push(ScratchDoubleReg);
-
- Label failure, tenuredObject, allocated;
- masm.branch32(Assembler::NotEqual, newKindReg, Imm32(GenericObject), &tenuredObject);
- masm.branchTest32(Assembler::NonZero, AbsoluteAddress(group->addressOfFlags()),
- Imm32(OBJECT_FLAG_PRE_TENURE), &tenuredObject);
-
- // Allocate an object in the nursery
- masm.createGCObject(object, scratch1, templateObject, gc::DefaultHeap, &failure,
- /* initFixedSlots = */ false);
-
- masm.jump(&allocated);
- masm.bind(&tenuredObject);
-
- // Allocate an object in the tenured heap.
- masm.createGCObject(object, scratch1, templateObject, gc::TenuredHeap, &failure,
- /* initFixedSlots = */ false);
-
- // If any of the properties being stored are in the nursery, add a store
- // buffer entry for the new object.
- Label postBarrier;
- for (size_t i = 0; i < layout.properties().length(); i++) {
- const UnboxedLayout::Property& property = layout.properties()[i];
- if (property.type == JSVAL_TYPE_OBJECT) {
- Address valueAddress(propertiesReg, i * sizeof(IdValuePair) + offsetof(IdValuePair, value));
- Label notObject;
- masm.branchTestObject(Assembler::NotEqual, valueAddress, &notObject);
- Register valueObject = masm.extractObject(valueAddress, scratch1);
- masm.branchPtrInNurseryChunk(Assembler::Equal, valueObject, scratch2, &postBarrier);
- masm.bind(&notObject);
- }
- }
-
- masm.jump(&allocated);
- masm.bind(&postBarrier);
-
- LiveGeneralRegisterSet liveVolatileRegisters;
- liveVolatileRegisters.add(propertiesReg);
- if (object.volatile_())
- liveVolatileRegisters.add(object);
- masm.PushRegsInMask(liveVolatileRegisters);
-
- masm.mov(ImmPtr(cx->runtime()), scratch1);
- masm.setupUnalignedABICall(scratch2);
- masm.passABIArg(scratch1);
- masm.passABIArg(object);
- masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, PostWriteBarrier));
-
- masm.PopRegsInMask(liveVolatileRegisters);
-
- masm.bind(&allocated);
-
- ValueOperand valueOperand;
-#ifdef JS_NUNBOX32
- valueOperand = ValueOperand(scratch1, scratch2);
-#else
- valueOperand = ValueOperand(scratch1);
-#endif
-
- Label failureStoreOther, failureStoreObject;
-
- for (size_t i = 0; i < layout.properties().length(); i++) {
- const UnboxedLayout::Property& property = layout.properties()[i];
- Address valueAddress(propertiesReg, i * sizeof(IdValuePair) + offsetof(IdValuePair, value));
- Address targetAddress(object, UnboxedPlainObject::offsetOfData() + property.offset);
-
- masm.loadValue(valueAddress, valueOperand);
-
- if (property.type == JSVAL_TYPE_OBJECT) {
- HeapTypeSet* types = group->maybeGetProperty(IdToTypeId(NameToId(property.name)));
-
- Label notObject;
- masm.branchTestObject(Assembler::NotEqual, valueOperand,
- types->mightBeMIRType(MIRType::Null) ? &notObject : &failureStoreObject);
-
- Register payloadReg = masm.extractObject(valueOperand, scratch1);
-
- if (!types->hasType(TypeSet::AnyObjectType())) {
- Register scratch = (payloadReg == scratch1) ? scratch2 : scratch1;
- masm.guardObjectType(payloadReg, types, scratch, &failureStoreObject);
- }
-
- masm.storeUnboxedProperty(targetAddress, JSVAL_TYPE_OBJECT,
- TypedOrValueRegister(MIRType::Object,
- AnyRegister(payloadReg)), nullptr);
-
- if (notObject.used()) {
- Label done;
- masm.jump(&done);
- masm.bind(&notObject);
- masm.branchTestNull(Assembler::NotEqual, valueOperand, &failureStoreOther);
- masm.storeUnboxedProperty(targetAddress, JSVAL_TYPE_OBJECT, NullValue(), nullptr);
- masm.bind(&done);
- }
- } else {
- masm.storeUnboxedProperty(targetAddress, property.type,
- ConstantOrRegister(valueOperand), &failureStoreOther);
- }
- }
-
- Label done;
- masm.bind(&done);
-
- if (object != ReturnReg)
- masm.movePtr(object, ReturnReg);
-
- // Restore non-volatile registers which were saved on entry.
- if (ScratchDoubleReg.volatile_())
- masm.pop(ScratchDoubleReg);
- masm.PopRegsInMask(savedNonVolatileRegisters);
-
- masm.abiret();
-
- masm.bind(&failureStoreOther);
-
- // There was a failure while storing a value which cannot be stored at all
- // in the unboxed object. Initialize the object so it is safe for GC and
- // return null.
- masm.initUnboxedObjectContents(object, templateObject);
-
- masm.bind(&failure);
-
- masm.movePtr(ImmWord(0), object);
- masm.jump(&done);
-
- masm.bind(&failureStoreObject);
-
- // There was a failure while storing a value to an object slot of the
- // unboxed object. If the value is storable, the failure occurred due to
- // incomplete type information in the object, so return a token to trigger
- // regeneration of the jitcode after a new object is created in the VM.
- {
- Label isObject;
- masm.branchTestObject(Assembler::Equal, valueOperand, &isObject);
- masm.branchTestNull(Assembler::NotEqual, valueOperand, &failureStoreOther);
- masm.bind(&isObject);
- }
-
- // Initialize the object so it is safe for GC.
- masm.initUnboxedObjectContents(object, templateObject);
-
- masm.movePtr(ImmWord(CLEAR_CONSTRUCTOR_CODE_TOKEN), object);
- masm.jump(&done);
-
- Linker linker(masm);
- AutoFlushICache afc("UnboxedObject");
- JitCode* code = linker.newCode<NoGC>(cx, OTHER_CODE);
- if (!code)
- return false;
-
- layout.setConstructorCode(code);
- return true;
+ // *** STUB ***
+ return false;
}
void