summaryrefslogtreecommitdiffstats
path: root/js/src/jit/BaselineIC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit/BaselineIC.cpp')
-rw-r--r--js/src/jit/BaselineIC.cpp546
1 files changed, 90 insertions, 456 deletions
diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp
index 863c61161..9530f65fa 100644
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -10,6 +10,8 @@
#include "mozilla/SizePrintfMacros.h"
#include "mozilla/TemplateLib.h"
+#include "jsfriendapi.h"
+#include "jsfun.h"
#include "jslibmath.h"
#include "jstypes.h"
@@ -42,8 +44,8 @@
#include "jit/shared/Lowering-shared-inl.h"
#include "vm/EnvironmentObject-inl.h"
#include "vm/Interpreter-inl.h"
+#include "vm/NativeObject-inl.h"
#include "vm/StringObject-inl.h"
-#include "vm/UnboxedObject-inl.h"
using mozilla::DebugOnly;
@@ -289,7 +291,7 @@ DoTypeUpdateFallback(JSContext* cx, BaselineFrame* frame, ICUpdatedStub* stub, H
case ICStub::SetProp_Native:
case ICStub::SetProp_NativeAdd:
case ICStub::SetProp_Unboxed: {
- MOZ_ASSERT(obj->isNative() || obj->is<UnboxedPlainObject>());
+ MOZ_ASSERT(obj->isNative());
jsbytecode* pc = stub->getChainFallback()->icEntry()->pc(script);
if (*pc == JSOP_SETALIASEDVAR || *pc == JSOP_INITALIASEDLEXICAL)
id = NameToId(EnvironmentCoordinateName(cx->caches.envCoordinateNameCache, script, pc));
@@ -321,7 +323,14 @@ DoTypeUpdateFallback(JSContext* cx, BaselineFrame* frame, ICUpdatedStub* stub, H
MOZ_CRASH("Invalid stub");
}
- return stub->addUpdateStubForValue(cx, script /* = outerScript */, obj, id, value);
+ if (!stub->addUpdateStubForValue(cx, script /* = outerScript */, obj, id, value)) {
+ // The calling JIT code assumes this function is infallible (for
+ // instance we may reallocate dynamic slots before calling this),
+ // so ignore OOMs if we failed to attach a stub.
+ cx->recoverFromOutOfMemory();
+ }
+
+ return true;
}
typedef bool (*DoTypeUpdateFallbackFn)(JSContext*, BaselineFrame*, ICUpdatedStub*, HandleValue,
@@ -732,11 +741,6 @@ LastPropertyForSetProp(JSObject* obj)
if (obj->isNative())
return obj->as<NativeObject>().lastProperty();
- if (obj->is<UnboxedPlainObject>()) {
- UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando();
- return expando ? expando->lastProperty() : nullptr;
- }
-
return nullptr;
}
@@ -1153,56 +1157,6 @@ TryAttachNativeOrUnboxedGetValueElemStub(JSContext* cx, HandleScript script, jsb
ICStub* monitorStub = stub->fallbackMonitorStub()->firstMonitorStub();
- if (obj->is<UnboxedPlainObject>() && holder == obj) {
- const UnboxedLayout::Property* property = obj->as<UnboxedPlainObject>().layout().lookup(id);
-
- // Once unboxed objects support symbol-keys, we need to change the following accordingly
- MOZ_ASSERT_IF(!keyVal.isString(), !property);
-
- if (property) {
- if (!cx->runtime()->jitSupportsFloatingPoint)
- return true;
-
- RootedPropertyName name(cx, JSID_TO_ATOM(id)->asPropertyName());
- ICGetElemNativeCompiler<PropertyName*> compiler(cx, ICStub::GetElem_UnboxedPropertyName,
- monitorStub, obj, holder,
- name,
- ICGetElemNativeStub::UnboxedProperty,
- needsAtomize, property->offset +
- UnboxedPlainObject::offsetOfData(),
- property->type);
- ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
- if (!newStub)
- return false;
-
- stub->addNewStub(newStub);
- *attached = true;
- return true;
- }
-
- Shape* shape = obj->as<UnboxedPlainObject>().maybeExpando()->lookup(cx, id);
- if (!shape->hasDefaultGetter() || !shape->hasSlot())
- return true;
-
- bool isFixedSlot;
- uint32_t offset;
- GetFixedOrDynamicSlotOffset(shape, &isFixedSlot, &offset);
-
- ICGetElemNativeStub::AccessType acctype =
- isFixedSlot ? ICGetElemNativeStub::FixedSlot
- : ICGetElemNativeStub::DynamicSlot;
- ICGetElemNativeCompiler<T> compiler(cx, getGetElemStubKind<T>(ICStub::GetElem_NativeSlotName),
- monitorStub, obj, holder, key,
- acctype, needsAtomize, offset);
- ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
- if (!newStub)
- return false;
-
- stub->addNewStub(newStub);
- *attached = true;
- return true;
- }
-
if (!holder->isNative())
return true;
@@ -1366,7 +1320,7 @@ IsNativeDenseElementAccess(HandleObject obj, HandleValue key)
static bool
IsNativeOrUnboxedDenseElementAccess(HandleObject obj, HandleValue key)
{
- if (!obj->isNative() && !obj->is<UnboxedArrayObject>())
+ if (!obj->isNative())
return false;
if (key.isInt32() && key.toInt32() >= 0 && !obj->is<TypedArrayObject>())
return true;
@@ -1450,7 +1404,7 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_
}
// Check for NativeObject[id] and UnboxedPlainObject[id] shape-optimizable accesses.
- if (obj->isNative() || obj->is<UnboxedPlainObject>()) {
+ if (obj->isNative()) {
RootedScript rootedScript(cx, script);
if (rhs.isString()) {
if (!TryAttachNativeOrUnboxedGetValueElemStub<PropertyName*>(cx, rootedScript, pc, stub,
@@ -1470,20 +1424,6 @@ TryAttachGetElemStub(JSContext* cx, JSScript* script, jsbytecode* pc, ICGetElem_
script = rootedScript;
}
- // Check for UnboxedArray[int] accesses.
- if (obj->is<UnboxedArrayObject>() && rhs.isInt32() && rhs.toInt32() >= 0) {
- JitSpew(JitSpew_BaselineIC, " Generating GetElem(UnboxedArray[Int32]) stub");
- ICGetElem_UnboxedArray::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub(),
- obj->group());
- ICStub* unboxedStub = compiler.getStub(compiler.getStubSpace(script));
- if (!unboxedStub)
- return false;
-
- stub->addNewStub(unboxedStub);
- *attached = true;
- return true;
- }
-
// Check for TypedArray[int] => Number and TypedObject[int] => Number accesses.
if ((obj->is<TypedArrayObject>() || IsPrimitiveArrayTypedObject(obj)) &&
rhs.isNumber() &&
@@ -1876,14 +1816,6 @@ ICGetElemNativeCompiler<T>::generateStubCode(MacroAssembler& masm)
Register holderReg;
if (obj_ == holder_) {
holderReg = objReg;
-
- if (obj_->is<UnboxedPlainObject>() && acctype_ != ICGetElemNativeStub::UnboxedProperty) {
- // The property will be loaded off the unboxed expando.
- masm.push(R1.scratchReg());
- popR1 = true;
- holderReg = R1.scratchReg();
- masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg);
- }
} else {
// Shape guard holder.
if (regs.empty()) {
@@ -1934,13 +1866,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);
@@ -2090,56 +2015,6 @@ ICGetElem_Dense::Compiler::generateStubCode(MacroAssembler& masm)
}
//
-// GetElem_UnboxedArray
-//
-
-bool
-ICGetElem_UnboxedArray::Compiler::generateStubCode(MacroAssembler& masm)
-{
- MOZ_ASSERT(engine_ == Engine::Baseline);
-
- Label failure;
- masm.branchTestObject(Assembler::NotEqual, R0, &failure);
- masm.branchTestInt32(Assembler::NotEqual, R1, &failure);
-
- AllocatableGeneralRegisterSet regs(availableGeneralRegs(2));
- Register scratchReg = regs.takeAny();
-
- // Unbox R0 and group guard.
- Register obj = masm.extractObject(R0, ExtractTemp0);
- masm.loadPtr(Address(ICStubReg, ICGetElem_UnboxedArray::offsetOfGroup()), scratchReg);
- masm.branchTestObjGroup(Assembler::NotEqual, obj, scratchReg, &failure);
-
- // Unbox key.
- Register key = masm.extractInt32(R1, ExtractTemp1);
-
- // Bounds check.
- masm.load32(Address(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength()),
- scratchReg);
- masm.and32(Imm32(UnboxedArrayObject::InitializedLengthMask), scratchReg);
- masm.branch32(Assembler::BelowOrEqual, scratchReg, key, &failure);
-
- // Load obj->elements.
- masm.loadPtr(Address(obj, UnboxedArrayObject::offsetOfElements()), scratchReg);
-
- // Load value.
- size_t width = UnboxedTypeSize(elementType_);
- BaseIndex addr(scratchReg, key, ScaleFromElemWidth(width));
- masm.loadUnboxedProperty(addr, elementType_, R0);
-
- // Only monitor the result if its type might change.
- if (elementType_ == JSVAL_TYPE_OBJECT)
- EmitEnterTypeMonitorIC(masm);
- else
- EmitReturnFromIC(masm);
-
- // Failure case - jump to next stub
- masm.bind(&failure);
- EmitStubGuardFailure(masm);
- return true;
-}
-
-//
// GetElem_TypedArray
//
@@ -2387,14 +2262,20 @@ DenseOrUnboxedArraySetElemStubExists(JSContext* cx, ICStub::Kind kind,
for (ICStubConstIterator iter = stub->beginChainConst(); !iter.atEnd(); iter++) {
if (kind == ICStub::SetElem_DenseOrUnboxedArray && iter->isSetElem_DenseOrUnboxedArray()) {
ICSetElem_DenseOrUnboxedArray* nstub = iter->toSetElem_DenseOrUnboxedArray();
- if (obj->maybeShape() == nstub->shape() && obj->getGroup(cx) == nstub->group())
+ if (obj->maybeShape() == nstub->shape() &&
+ JSObject::getGroup(cx, obj) == nstub->group())
+ {
return true;
+ }
}
if (kind == ICStub::SetElem_DenseOrUnboxedArrayAdd && iter->isSetElem_DenseOrUnboxedArrayAdd()) {
ICSetElem_DenseOrUnboxedArrayAdd* nstub = iter->toSetElem_DenseOrUnboxedArrayAdd();
- if (obj->getGroup(cx) == nstub->group() && SetElemAddHasSameShapes(nstub, obj))
+ if (JSObject::getGroup(cx, obj) == nstub->group() &&
+ SetElemAddHasSameShapes(nstub, obj))
+ {
return true;
+ }
}
}
return false;
@@ -2437,8 +2318,8 @@ CanOptimizeDenseOrUnboxedArraySetElem(JSObject* obj, uint32_t index,
Shape* oldShape, uint32_t oldCapacity, uint32_t oldInitLength,
bool* isAddingCaseOut, size_t* protoDepthOut)
{
- uint32_t initLength = GetAnyBoxedOrUnboxedInitializedLength(obj);
- uint32_t capacity = GetAnyBoxedOrUnboxedCapacity(obj);
+ uint32_t initLength = obj->as<NativeObject>().getDenseInitializedLength();
+ uint32_t capacity = obj->as<NativeObject>().getDenseCapacity();
*isAddingCaseOut = false;
*protoDepthOut = 0;
@@ -2447,10 +2328,6 @@ CanOptimizeDenseOrUnboxedArraySetElem(JSObject* obj, uint32_t index,
if (initLength < oldInitLength || capacity < oldCapacity)
return false;
- // Unboxed arrays need to be able to emit floating point code.
- if (obj->is<UnboxedArrayObject>() && !obj->runtimeFromMainThread()->jitSupportsFloatingPoint)
- return false;
-
Shape* shape = obj->maybeShape();
// Cannot optimize if the shape changed.
@@ -2532,8 +2409,8 @@ DoSetElemFallback(JSContext* cx, BaselineFrame* frame, ICSetElem_Fallback* stub_
uint32_t oldCapacity = 0;
uint32_t oldInitLength = 0;
if (index.isInt32() && index.toInt32() >= 0) {
- oldCapacity = GetAnyBoxedOrUnboxedCapacity(obj);
- oldInitLength = GetAnyBoxedOrUnboxedInitializedLength(obj);
+ oldCapacity = obj->as<NativeObject>().getDenseCapacity();
+ oldInitLength = obj->as<NativeObject>().getDenseInitializedLength();
}
if (op == JSOP_INITELEM || op == JSOP_INITHIDDENELEM) {
@@ -2584,7 +2461,7 @@ DoSetElemFallback(JSContext* cx, BaselineFrame* frame, ICSetElem_Fallback* stub_
&addingCase, &protoDepth))
{
RootedShape shape(cx, obj->maybeShape());
- RootedObjectGroup group(cx, obj->getGroup(cx));
+ RootedObjectGroup group(cx, JSObject::getGroup(cx, obj));
if (!group)
return false;
@@ -2741,18 +2618,6 @@ BaselineScript::noteArrayWriteHole(uint32_t pcOffset)
// SetElem_DenseOrUnboxedArray
//
-template <typename T>
-void
-EmitUnboxedPreBarrierForBaseline(MacroAssembler &masm, T address, JSValueType type)
-{
- if (type == JSVAL_TYPE_OBJECT)
- EmitPreBarrier(masm, address, MIRType::Object);
- else if (type == JSVAL_TYPE_STRING)
- EmitPreBarrier(masm, address, MIRType::String);
- else
- MOZ_ASSERT(!UnboxedTypeNeedsPreBarrier(type));
-}
-
bool
ICSetElem_DenseOrUnboxedArray::Compiler::generateStubCode(MacroAssembler& masm)
{
@@ -2871,29 +2736,6 @@ ICSetElem_DenseOrUnboxedArray::Compiler::generateStubCode(MacroAssembler& masm)
masm.loadValue(valueAddr, tmpVal);
EmitPreBarrier(masm, element, MIRType::Value);
masm.storeValue(tmpVal, element);
- } else {
- // Set element on an unboxed array.
-
- // Bounds check.
- Address initLength(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength());
- masm.load32(initLength, scratchReg);
- masm.and32(Imm32(UnboxedArrayObject::InitializedLengthMask), scratchReg);
- masm.branch32(Assembler::BelowOrEqual, scratchReg, key, &failure);
-
- // Load obj->elements.
- masm.loadPtr(Address(obj, UnboxedArrayObject::offsetOfElements()), scratchReg);
-
- // Compute the address being written to.
- BaseIndex address(scratchReg, key, ScaleFromElemWidth(UnboxedTypeSize(unboxedType_)));
-
- EmitUnboxedPreBarrierForBaseline(masm, address, unboxedType_);
-
- Address valueAddr(masm.getStackPointer(), ICStackValueOffset + sizeof(Value));
- masm.Push(R0);
- masm.loadValue(valueAddr, R0);
- masm.storeUnboxedProperty(address, unboxedType_,
- ConstantOrRegister(TypedOrValueRegister(R0)), &failurePopR0);
- masm.Pop(R0);
}
EmitReturnFromIC(masm);
@@ -3087,40 +2929,6 @@ ICSetElemDenseOrUnboxedArrayAddCompiler::generateStubCode(MacroAssembler& masm)
BaseIndex element(scratchReg, key, TimesEight);
masm.loadValue(valueAddr, tmpVal);
masm.storeValue(tmpVal, element);
- } else {
- // Adding element to an unboxed array.
-
- // Bounds check (key == initLength)
- Address initLengthAddr(obj, UnboxedArrayObject::offsetOfCapacityIndexAndInitializedLength());
- masm.load32(initLengthAddr, scratchReg);
- masm.and32(Imm32(UnboxedArrayObject::InitializedLengthMask), scratchReg);
- masm.branch32(Assembler::NotEqual, scratchReg, key, &failure);
-
- // Capacity check.
- masm.checkUnboxedArrayCapacity(obj, RegisterOrInt32Constant(key), scratchReg, &failure);
-
- // Load obj->elements.
- masm.loadPtr(Address(obj, UnboxedArrayObject::offsetOfElements()), scratchReg);
-
- // Write the value first, since this can fail. No need for pre-barrier
- // since we're not overwriting an old value.
- masm.Push(R0);
- Address valueAddr(masm.getStackPointer(), ICStackValueOffset + sizeof(Value));
- masm.loadValue(valueAddr, R0);
- BaseIndex address(scratchReg, key, ScaleFromElemWidth(UnboxedTypeSize(unboxedType_)));
- masm.storeUnboxedProperty(address, unboxedType_,
- ConstantOrRegister(TypedOrValueRegister(R0)), &failurePopR0);
- masm.Pop(R0);
-
- // Increment initialized length.
- masm.add32(Imm32(1), initLengthAddr);
-
- // If length is now <= key, increment length.
- Address lengthAddr(obj, UnboxedArrayObject::offsetOfLength());
- Label skipIncrementLength;
- masm.branch32(Assembler::Above, lengthAddr, key, &skipIncrementLength);
- masm.add32(Imm32(1), lengthAddr);
- masm.bind(&skipIncrementLength);
}
EmitReturnFromIC(masm);
@@ -4245,9 +4053,6 @@ TryAttachSetValuePropStub(JSContext* cx, HandleScript script, jsbytecode* pc, IC
{
MOZ_ASSERT(!*attached);
- if (obj->watched())
- return true;
-
RootedShape shape(cx);
RootedObject holder(cx);
if (!EffectlesslyLookupProperty(cx, obj, id, &holder, &shape))
@@ -4256,18 +4061,7 @@ TryAttachSetValuePropStub(JSContext* cx, HandleScript script, jsbytecode* pc, IC
return true;
if (!obj->isNative()) {
- if (obj->is<UnboxedPlainObject>()) {
- UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando();
- if (expando) {
- shape = expando->lookup(cx, name);
- if (!shape)
- return true;
- } else {
- return true;
- }
- } else {
- return true;
- }
+ return true;
}
size_t chainDepth;
@@ -4354,9 +4148,6 @@ TryAttachSetAccessorPropStub(JSContext* cx, HandleScript script, jsbytecode* pc,
MOZ_ASSERT(!*attached);
MOZ_ASSERT(!*isTemporarilyUnoptimizable);
- if (obj->watched())
- return true;
-
RootedShape shape(cx);
RootedObject holder(cx);
if (!EffectlesslyLookupProperty(cx, obj, id, &holder, &shape))
@@ -4418,40 +4209,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)
@@ -4529,17 +4286,11 @@ DoSetPropFallback(JSContext* cx, BaselineFrame* frame, ICSetProp_Fallback* stub_
if (!obj)
return false;
RootedShape oldShape(cx, obj->maybeShape());
- RootedObjectGroup oldGroup(cx, obj->getGroup(cx));
+ RootedObjectGroup oldGroup(cx, JSObject::getGroup(cx, obj));
if (!oldGroup)
return false;
RootedReceiverGuard oldGuard(cx, ReceiverGuard(obj));
- if (obj->is<UnboxedPlainObject>()) {
- MOZ_ASSERT(!oldShape);
- if (UnboxedExpandoObject* expando = obj->as<UnboxedPlainObject>().maybeExpando())
- oldShape = expando->lastProperty();
- }
-
bool attached = false;
// There are some reasons we can fail to attach a stub that are temporary.
// We want to avoid calling noteUnoptimizableAccess() if the reason we
@@ -4612,15 +4363,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;
@@ -4703,20 +4445,7 @@ GuardGroupAndShapeMaybeUnboxedExpando(MacroAssembler& masm, JSObject* obj,
// Guard against shape or expando shape.
masm.loadPtr(Address(ICStubReg, offsetOfShape), scratch);
- if (obj->is<UnboxedPlainObject>()) {
- Address expandoAddress(object, UnboxedPlainObject::offsetOfExpando());
- masm.branchPtr(Assembler::Equal, expandoAddress, ImmWord(0), failure);
- Label done;
- masm.push(object);
- masm.loadPtr(expandoAddress, object);
- masm.branchTestObjShape(Assembler::Equal, object, scratch, &done);
- masm.pop(object);
- masm.jump(failure);
- masm.bind(&done);
- masm.pop(object);
- } else {
- masm.branchTestObjShape(Assembler::NotEqual, object, scratch, failure);
- }
+ masm.branchTestObjShape(Assembler::NotEqual, object, scratch, failure);
}
bool
@@ -4755,13 +4484,7 @@ ICSetProp_Native::Compiler::generateStubCode(MacroAssembler& masm)
regs.takeUnchecked(objReg);
Register holderReg;
- if (obj_->is<UnboxedPlainObject>()) {
- // We are loading off the expando object, so use that for the holder.
- holderReg = regs.takeAny();
- masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg);
- if (!isFixedSlot_)
- masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), holderReg);
- } else if (isFixedSlot_) {
+ if (isFixedSlot_) {
holderReg = objReg;
} else {
holderReg = regs.takeAny();
@@ -4898,31 +4621,17 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler& masm)
regs.add(R0);
regs.takeUnchecked(objReg);
- if (obj_->is<UnboxedPlainObject>()) {
- holderReg = regs.takeAny();
- masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg);
-
- // Write the expando object's new shape.
- Address shapeAddr(holderReg, ShapedObject::offsetOfShape());
- EmitPreBarrier(masm, shapeAddr, MIRType::Shape);
- masm.loadPtr(Address(ICStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch);
- masm.storePtr(scratch, shapeAddr);
+ // Write the object's new shape.
+ Address shapeAddr(objReg, ShapedObject::offsetOfShape());
+ EmitPreBarrier(masm, shapeAddr, MIRType::Shape);
+ masm.loadPtr(Address(ICStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch);
+ masm.storePtr(scratch, shapeAddr);
- if (!isFixedSlot_)
- masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), holderReg);
+ if (isFixedSlot_) {
+ holderReg = objReg;
} else {
- // Write the object's new shape.
- Address shapeAddr(objReg, ShapedObject::offsetOfShape());
- EmitPreBarrier(masm, shapeAddr, MIRType::Shape);
- masm.loadPtr(Address(ICStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch);
- masm.storePtr(scratch, shapeAddr);
-
- if (isFixedSlot_) {
- holderReg = objReg;
- } else {
- holderReg = regs.takeAny();
- masm.loadPtr(Address(objReg, NativeObject::offsetOfSlots()), holderReg);
- }
+ holderReg = regs.takeAny();
+ masm.loadPtr(Address(objReg, NativeObject::offsetOfSlots()), holderReg);
}
// Perform the store. No write barrier required since this is a new
@@ -4954,70 +4663,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);
@@ -5490,13 +5135,6 @@ GetTemplateObjectForSimd(JSContext* cx, JSFunction* target, MutableHandleObject
return true;
}
-static void
-EnsureArrayGroupAnalyzed(JSContext* cx, JSObject* obj)
-{
- if (PreliminaryObjectArrayWithTemplate* objects = obj->group()->maybePreliminaryObjects())
- objects->maybeAnalyze(cx, obj->group(), /* forceAnalyze = */ true);
-}
-
static bool
GetTemplateObjectForNative(JSContext* cx, HandleFunction target, const CallArgs& args,
MutableHandleObject res, bool* skipAttach)
@@ -5528,10 +5166,7 @@ GetTemplateObjectForNative(JSContext* cx, HandleFunction target, const CallArgs&
// With this and other array templates, analyze the group so that
// we don't end up with a template whose structure might change later.
res.set(NewFullyAllocatedArrayForCallingAllocationSite(cx, count, TenuredObject));
- if (!res)
- return false;
- EnsureArrayGroupAnalyzed(cx, res);
- return true;
+ return !!res;
}
}
@@ -5549,18 +5184,14 @@ GetTemplateObjectForNative(JSContext* cx, HandleFunction target, const CallArgs&
if (native == js::array_slice) {
if (args.thisv().isObject()) {
- JSObject* obj = &args.thisv().toObject();
+ RootedObject obj(cx, &args.thisv().toObject());
if (!obj->isSingleton()) {
if (obj->group()->maybePreliminaryObjects()) {
*skipAttach = true;
return true;
}
- res.set(NewFullyAllocatedArrayTryReuseGroup(cx, &args.thisv().toObject(), 0,
- TenuredObject));
- if (!res)
- return false;
- EnsureArrayGroupAnalyzed(cx, res);
- return true;
+ res.set(NewFullyAllocatedArrayTryReuseGroup(cx, obj, 0, TenuredObject));
+ return !!res;
}
}
}
@@ -5577,10 +5208,7 @@ GetTemplateObjectForNative(JSContext* cx, HandleFunction target, const CallArgs&
}
res.set(NewFullyAllocatedArrayForCallingAllocationSite(cx, 0, TenuredObject));
- if (!res)
- return false;
- EnsureArrayGroupAnalyzed(cx, res);
- return true;
+ return !!res;
}
if (native == StringConstructor) {
@@ -5793,7 +5421,7 @@ TryAttachCallStub(JSContext* cx, ICCall_Fallback* stub, HandleScript script, jsb
if (!thisObject)
return false;
- if (thisObject->is<PlainObject>() || thisObject->is<UnboxedPlainObject>())
+ if (thisObject->is<PlainObject>())
templateObject = thisObject;
}
@@ -5869,11 +5497,17 @@ TryAttachCallStub(JSContext* cx, ICCall_Fallback* stub, HandleScript script, jsb
MOZ_ASSERT_IF(templateObject, !templateObject->group()->maybePreliminaryObjects());
}
+ bool ignoresReturnValue = false;
+ if (op == JSOP_CALL_IGNORES_RV && fun->isNative()) {
+ const JSJitInfo* jitInfo = fun->jitInfo();
+ ignoresReturnValue = jitInfo && jitInfo->type() == JSJitInfo::IgnoresReturnValueNative;
+ }
+
JitSpew(JitSpew_BaselineIC, " Generating Call_Native stub (fun=%p, cons=%s, spread=%s)",
fun.get(), constructing ? "yes" : "no", isSpread ? "yes" : "no");
ICCall_Native::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub(),
- fun, templateObject, constructing, isSpread,
- script->pcToOffset(pc));
+ fun, templateObject, constructing, ignoresReturnValue,
+ isSpread, script->pcToOffset(pc));
ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
if (!newStub)
return false;
@@ -5887,15 +5521,24 @@ TryAttachCallStub(JSContext* cx, ICCall_Fallback* stub, HandleScript script, jsb
}
static bool
-CopyArray(JSContext* cx, HandleObject obj, MutableHandleValue result)
+CopyArray(JSContext* cx, HandleArrayObject arr, MutableHandleValue result)
{
- uint32_t length = GetAnyBoxedOrUnboxedArrayLength(obj);
- JSObject* nobj = NewFullyAllocatedArrayTryReuseGroup(cx, obj, length, TenuredObject);
+ uint32_t length = arr->length();
+ ArrayObject* nobj = NewFullyAllocatedArrayTryReuseGroup(cx, arr, length, TenuredObject);
if (!nobj)
return false;
- EnsureArrayGroupAnalyzed(cx, nobj);
- CopyAnyBoxedOrUnboxedDenseElements(cx, nobj, obj, 0, 0, length);
-
+
+ MOZ_ASSERT(arr->isNative());
+ MOZ_ASSERT(nobj->isNative());
+ MOZ_ASSERT(nobj->as<NativeObject>().getDenseInitializedLength() == 0);
+ MOZ_ASSERT(arr->as<NativeObject>().getDenseInitializedLength() >= length);
+ MOZ_ASSERT(nobj->as<NativeObject>().getDenseCapacity() >= length);
+
+ nobj->as<NativeObject>().setDenseInitializedLength(length);
+
+ const Value* vp = arr->as<NativeObject>().getDenseElements();
+ nobj->as<NativeObject>().initDenseElements(0, vp, length);
+
result.setObject(*nobj);
return true;
}
@@ -5926,26 +5569,22 @@ TryAttachStringSplit(JSContext* cx, ICCall_Fallback* stub, HandleScript script,
RootedValue arr(cx);
// Copy the array before storing in stub.
- if (!CopyArray(cx, obj, &arr))
+ if (!CopyArray(cx, obj.as<ArrayObject>(), &arr))
return false;
// Atomize all elements of the array.
- RootedObject arrObj(cx, &arr.toObject());
- uint32_t initLength = GetAnyBoxedOrUnboxedArrayLength(arrObj);
+ RootedArrayObject arrObj(cx, &arr.toObject().as<ArrayObject>());
+ uint32_t initLength = arrObj->length();
for (uint32_t i = 0; i < initLength; i++) {
- JSAtom* str = js::AtomizeString(cx, GetAnyBoxedOrUnboxedDenseElement(arrObj, i).toString());
+ JSAtom* str = js::AtomizeString(cx, arrObj->getDenseElement(i).toString());
if (!str)
return false;
- if (!SetAnyBoxedOrUnboxedDenseElement(cx, arrObj, i, StringValue(str))) {
- // The value could not be stored to an unboxed dense element.
- return true;
- }
+ arrObj->setDenseElementWithType(cx, i, StringValue(str));
}
ICCall_StringSplit::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub(),
- script->pcToOffset(pc), str, sep,
- arr);
+ script->pcToOffset(pc), str, sep, arrObj);
ICStub* newStub = compiler.getStub(compiler.getStubSpace(script));
if (!newStub)
return false;
@@ -5971,12 +5610,14 @@ DoCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub_, uint
MOZ_ASSERT(argc == GET_ARGC(pc));
bool constructing = (op == JSOP_NEW);
+ bool ignoresReturnValue = (op == JSOP_CALL_IGNORES_RV);
// Ensure vp array is rooted - we may GC in here.
size_t numValues = argc + 2 + constructing;
AutoArrayRooter vpRoot(cx, numValues, vp);
- CallArgs callArgs = CallArgsFromSp(argc + constructing, vp + numValues, constructing);
+ CallArgs callArgs = CallArgsFromSp(argc + constructing, vp + numValues, constructing,
+ ignoresReturnValue);
RootedValue callee(cx, vp[0]);
// Handle funapply with JSOP_ARGUMENTS
@@ -6006,6 +5647,7 @@ DoCallFallback(JSContext* cx, BaselineFrame* frame, ICCall_Fallback* stub_, uint
return false;
} else {
MOZ_ASSERT(op == JSOP_CALL ||
+ op == JSOP_CALL_IGNORES_RV ||
op == JSOP_CALLITER ||
op == JSOP_FUNCALL ||
op == JSOP_FUNAPPLY ||
@@ -6830,7 +6472,7 @@ ICCallScriptedCompiler::generateStubCode(MacroAssembler& masm)
return true;
}
-typedef bool (*CopyArrayFn)(JSContext*, HandleObject, MutableHandleValue);
+typedef bool (*CopyArrayFn)(JSContext*, HandleArrayObject, MutableHandleValue);
static const VMFunction CopyArrayInfo = FunctionInfo<CopyArrayFn>(CopyArray, "CopyArray");
bool
@@ -7056,7 +6698,12 @@ ICCall_Native::Compiler::generateStubCode(MacroAssembler& masm)
// stub and use that instead of the original one.
masm.callWithABI(Address(ICStubReg, ICCall_Native::offsetOfNative()));
#else
- masm.callWithABI(Address(callee, JSFunction::offsetOfNativeOrScript()));
+ if (ignoresReturnValue_) {
+ masm.loadPtr(Address(callee, JSFunction::offsetOfJitInfo()), callee);
+ masm.callWithABI(Address(callee, JSJitInfo::offsetOfIgnoresReturnValueNative()));
+ } else {
+ masm.callWithABI(Address(callee, JSFunction::offsetOfNativeOrScript()));
+ }
#endif
// Test for failure.
@@ -8301,19 +7948,6 @@ ICGetElem_Dense::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorSt
return New<ICGetElem_Dense>(cx, space, other.jitCode(), firstMonitorStub, other.shape_);
}
-ICGetElem_UnboxedArray::ICGetElem_UnboxedArray(JitCode* stubCode, ICStub* firstMonitorStub,
- ObjectGroup *group)
- : ICMonitoredStub(GetElem_UnboxedArray, stubCode, firstMonitorStub),
- group_(group)
-{ }
-
-/* static */ ICGetElem_UnboxedArray*
-ICGetElem_UnboxedArray::Clone(JSContext* cx, ICStubSpace* space, ICStub* firstMonitorStub,
- ICGetElem_UnboxedArray& other)
-{
- return New<ICGetElem_UnboxedArray>(cx, space, other.jitCode(), firstMonitorStub, other.group_);
-}
-
ICGetElem_TypedArray::ICGetElem_TypedArray(JitCode* stubCode, Shape* shape, Scalar::Type type)
: ICStub(GetElem_TypedArray, stubCode),
shape_(shape)
@@ -8349,7 +7983,7 @@ ICUpdatedStub*
ICSetElemDenseOrUnboxedArrayAddCompiler::getStubSpecific(ICStubSpace* space,
Handle<ShapeVector> shapes)
{
- RootedObjectGroup group(cx, obj_->getGroup(cx));
+ RootedObjectGroup group(cx, JSObject::getGroup(cx, obj_));
if (!group)
return nullptr;
Rooted<JitCode*> stubCode(cx, getStubCode());
@@ -8486,7 +8120,7 @@ ICSetProp_Native::ICSetProp_Native(JitCode* stubCode, ObjectGroup* group, Shape*
ICSetProp_Native*
ICSetProp_Native::Compiler::getStub(ICStubSpace* space)
{
- RootedObjectGroup group(cx, obj_->getGroup(cx));
+ RootedObjectGroup group(cx, JSObject::getGroup(cx, obj_));
if (!group)
return nullptr;
@@ -8689,8 +8323,8 @@ static bool DoRestFallback(JSContext* cx, BaselineFrame* frame, ICRest_Fallback*
unsigned numRest = numActuals > numFormals ? numActuals - numFormals : 0;
Value* rest = frame->argv() + numFormals;
- JSObject* obj = ObjectGroup::newArrayObject(cx, rest, numRest, GenericObject,
- ObjectGroup::NewArrayKind::UnknownIndex);
+ ArrayObject* obj = ObjectGroup::newArrayObject(cx, rest, numRest, GenericObject,
+ ObjectGroup::NewArrayKind::UnknownIndex);
if (!obj)
return false;
res.setObject(*obj);