Skip to content
This repository has been archived by the owner on Aug 4, 2022. It is now read-only.

Commit

Permalink
Bug 1284634 - Introduce ShapedObject as a base class containing a sha…
Browse files Browse the repository at this point in the history
…pe field, for subclassing by NativeObject and ProxyObject. r=efaust
  • Loading branch information
jswalden committed Jul 6, 2016
1 parent abbe7a0 commit 5211692
Show file tree
Hide file tree
Showing 20 changed files with 140 additions and 76 deletions.
5 changes: 2 additions & 3 deletions js/src/builtin/TypedObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "builtin/TypedObjectConstants.h"
#include "js/Conversions.h"
#include "vm/ArrayBufferObject.h"
#include "vm/ShapedObject.h"

/*
* -------------
Expand Down Expand Up @@ -489,7 +490,7 @@ class TypedObjectModuleObject : public NativeObject {
};

/* Base type for transparent and opaque typed objects. */
class TypedObject : public JSObject
class TypedObject : public ShapedObject
{
static const bool IsTypedObjectClass = true;

Expand All @@ -502,8 +503,6 @@ class TypedObject : public JSObject
protected:
static const ObjectOps objectOps_;

GCPtrShape shape_;

static MOZ_MUST_USE bool obj_lookupProperty(JSContext* cx, HandleObject obj,
HandleId id, MutableHandleObject objp,
MutableHandleShape propp);
Expand Down
4 changes: 2 additions & 2 deletions js/src/jit/BaselineIC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4878,7 +4878,7 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler& masm)
masm.loadPtr(Address(objReg, UnboxedPlainObject::offsetOfExpando()), holderReg);

// Write the expando object's new shape.
Address shapeAddr(holderReg, JSObject::offsetOfShape());
Address shapeAddr(holderReg, ShapedObject::offsetOfShape());
EmitPreBarrier(masm, shapeAddr, MIRType::Shape);
masm.loadPtr(Address(ICStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch);
masm.storePtr(scratch, shapeAddr);
Expand All @@ -4887,7 +4887,7 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler& masm)
masm.loadPtr(Address(holderReg, NativeObject::offsetOfSlots()), holderReg);
} else {
// Write the object's new shape.
Address shapeAddr(objReg, JSObject::offsetOfShape());
Address shapeAddr(objReg, ShapedObject::offsetOfShape());
EmitPreBarrier(masm, shapeAddr, MIRType::Shape);
masm.loadPtr(Address(ICStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch);
masm.storePtr(scratch, shapeAddr);
Expand Down
6 changes: 3 additions & 3 deletions js/src/jit/CodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2114,7 +2114,7 @@ CodeGenerator::visitRegExpPrototypeOptimizable(LRegExpPrototypeOptimizable* ins)
RegExpCompartment::offsetOfOptimizableRegExpPrototypeShape();
masm.loadPtr(Address(temp, offset), temp);

masm.loadPtr(Address(object, JSObject::offsetOfShape()), output);
masm.loadPtr(Address(object, ShapedObject::offsetOfShape()), output);
masm.branchPtr(Assembler::NotEqual, output, temp, ool->entry());
masm.move32(Imm32(0x1), output);

Expand Down Expand Up @@ -2183,7 +2183,7 @@ CodeGenerator::visitRegExpInstanceOptimizable(LRegExpInstanceOptimizable* ins)
RegExpCompartment::offsetOfOptimizableRegExpInstanceShape();
masm.loadPtr(Address(temp, offset), temp);

masm.loadPtr(Address(object, JSObject::offsetOfShape()), output);
masm.loadPtr(Address(object, ShapedObject::offsetOfShape()), output);
masm.branchPtr(Assembler::NotEqual, output, temp, ool->entry());
masm.move32(Imm32(0x1), output);

Expand Down Expand Up @@ -3776,7 +3776,7 @@ LoadDOMPrivate(MacroAssembler& masm, Register obj, Register priv)
MOZ_ASSERT(obj != priv);

// Check shape->numFixedSlots != 0.
masm.loadPtr(Address(obj, JSObject::offsetOfShape()), priv);
masm.loadPtr(Address(obj, ShapedObject::offsetOfShape()), priv);

Label hasFixedSlots, done;
masm.branchTest32(Assembler::NonZero,
Expand Down
32 changes: 16 additions & 16 deletions js/src/jit/IonCaches.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ TestMatchingReceiver(MacroAssembler& masm, IonCache::StubAttacher& attacher,
MOZ_ASSERT(shape);

attacher.branchNextStubOrLabel(masm, Assembler::NotEqual,
Address(object, JSObject::offsetOfShape()),
Address(object, ShapedObject::offsetOfShape()),
ImmGCPtr(shape), failure);

if (alwaysCheckGroup)
Expand Down Expand Up @@ -733,7 +733,7 @@ CheckDOMProxyExpandoDoesNotShadow(JSContext* cx, MacroAssembler& masm, JSObject*
masm.branchTestObject(Assembler::NotEqual, tempVal, &failDOMProxyCheck);
masm.extractObject(tempVal, tempVal.scratchReg());
masm.branchPtr(Assembler::Equal,
Address(tempVal.scratchReg(), JSObject::offsetOfShape()),
Address(tempVal.scratchReg(), ShapedObject::offsetOfShape()),
ImmGCPtr(expandoVal.toObject().as<NativeObject>().lastProperty()),
&domProxyOk);
}
Expand Down Expand Up @@ -813,7 +813,7 @@ GenerateReadSlot(JSContext* cx, IonScript* ion, MacroAssembler& masm,
holderReg = scratchReg;
masm.movePtr(ImmGCPtr(holder), holderReg);
masm.branchPtr(Assembler::NotEqual,
Address(holderReg, JSObject::offsetOfShape()),
Address(holderReg, ShapedObject::offsetOfShape()),
ImmGCPtr(holder->as<NativeObject>().lastProperty()),
&prototypeFailures);
} else {
Expand All @@ -828,7 +828,7 @@ GenerateReadSlot(JSContext* cx, IonScript* ion, MacroAssembler& masm,
// Guard the shape of the current prototype.
MOZ_ASSERT(proto->hasStaticPrototype());
masm.branchPtr(Assembler::NotEqual,
Address(scratchReg, JSObject::offsetOfShape()),
Address(scratchReg, ShapedObject::offsetOfShape()),
ImmGCPtr(proto->as<NativeObject>().lastProperty()),
&prototypeFailures);

Expand Down Expand Up @@ -1117,7 +1117,7 @@ GenerateCallGetter(JSContext* cx, IonScript* ion, MacroAssembler& masm,
Register holderReg = scratchReg;
masm.movePtr(ImmGCPtr(holder), holderReg);
masm.branchPtr(Assembler::NotEqual,
Address(holderReg, JSObject::offsetOfShape()),
Address(holderReg, ShapedObject::offsetOfShape()),
ImmGCPtr(holder->as<NativeObject>().lastProperty()),
maybePopAndFail);

Expand Down Expand Up @@ -1768,7 +1768,7 @@ GetPropertyIC::tryAttachDOMProxyShadowed(JSContext* cx, HandleScript outerScript

// Guard on the shape of the object.
attacher.branchNextStubOrLabel(masm, Assembler::NotEqual,
Address(object(), JSObject::offsetOfShape()),
Address(object(), ShapedObject::offsetOfShape()),
ImmGCPtr(obj->maybeShape()),
&failures);

Expand Down Expand Up @@ -1840,7 +1840,7 @@ GetPropertyIC::tryAttachDOMProxyUnshadowed(JSContext* cx, HandleScript outerScri

// Guard on the shape of the object.
attacher.branchNextStubOrLabel(masm, Assembler::NotEqual,
Address(object(), JSObject::offsetOfShape()),
Address(object(), ShapedObject::offsetOfShape()),
ImmGCPtr(obj->maybeShape()),
&failures);

Expand All @@ -1859,7 +1859,7 @@ GetPropertyIC::tryAttachDOMProxyUnshadowed(JSContext* cx, HandleScript outerScri
// Guard on the holder of the property
masm.movePtr(ImmGCPtr(holder), holderReg);
masm.branchPtr(Assembler::NotEqual,
Address(holderReg, JSObject::offsetOfShape()),
Address(holderReg, ShapedObject::offsetOfShape()),
ImmGCPtr(holder->lastProperty()),
&failures);

Expand Down Expand Up @@ -2658,7 +2658,7 @@ SetPropertyIC::attachDOMProxyShadowed(JSContext* cx, HandleScript outerScript, I

// Guard on the shape of the object.
masm.branchPtr(Assembler::NotEqual,
Address(object(), JSObject::offsetOfShape()),
Address(object(), ShapedObject::offsetOfShape()),
ImmGCPtr(obj->maybeShape()), &failures);

// No need for more guards: we know this is a DOM proxy, since the shape
Expand Down Expand Up @@ -2697,7 +2697,7 @@ GenerateCallSetter(JSContext* cx, IonScript* ion, MacroAssembler& masm,

masm.movePtr(ImmGCPtr(holder), tempReg);
masm.branchPtr(Assembler::NotEqual,
Address(tempReg, JSObject::offsetOfShape()),
Address(tempReg, ShapedObject::offsetOfShape()),
ImmGCPtr(holder->as<NativeObject>().lastProperty()),
failure);
}
Expand Down Expand Up @@ -2936,7 +2936,7 @@ SetPropertyIC::attachDOMProxyUnshadowed(JSContext* cx, HandleScript outerScript,

// Guard on the shape of the object.
masm.branchPtr(Assembler::NotEqual,
Address(object(), JSObject::offsetOfShape()),
Address(object(), ShapedObject::offsetOfShape()),
ImmGCPtr(obj->maybeShape()), &failures);

// Guard that our expando object hasn't started shadowing this property.
Expand Down Expand Up @@ -3104,7 +3104,7 @@ GenerateAddSlot(JSContext* cx, MacroAssembler& masm, IonCache::StubAttacher& att
}

// Write the object or expando object's new shape.
Address shapeAddr(object, JSObject::offsetOfShape());
Address shapeAddr(object, ShapedObject::offsetOfShape());
if (cx->zone()->needsIncrementalBarrier())
masm.callPreBarrier(shapeAddr, MIRType::Shape);
masm.storePtr(ImmGCPtr(newShape), shapeAddr);
Expand Down Expand Up @@ -3879,7 +3879,7 @@ GenerateDenseElementHole(JSContext* cx, MacroAssembler& masm, IonCache::StubAtta
// Guard on the shape and group, to prevent non-dense elements from appearing.
Label failures;
attacher.branchNextStubOrLabel(masm, Assembler::NotEqual,
Address(object, JSObject::offsetOfShape()),
Address(object, ShapedObject::offsetOfShape()),
ImmGCPtr(obj->as<NativeObject>().lastProperty()), &failures);


Expand All @@ -3904,7 +3904,7 @@ GenerateDenseElementHole(JSContext* cx, MacroAssembler& masm, IonCache::StubAtta
}

// Make sure the shape matches, to avoid non-dense elements.
masm.branchPtr(Assembler::NotEqual, Address(scratchReg, JSObject::offsetOfShape()),
masm.branchPtr(Assembler::NotEqual, Address(scratchReg, ShapedObject::offsetOfShape()),
ImmGCPtr(pobj->as<NativeObject>().lastProperty()), &failures);

// Load elements vector.
Expand Down Expand Up @@ -4685,7 +4685,7 @@ GenerateScopeChainGuard(MacroAssembler& masm, JSObject* scopeObj,
return;
}

Address shapeAddr(scopeObjReg, JSObject::offsetOfShape());
Address shapeAddr(scopeObjReg, ShapedObject::offsetOfShape());
masm.branchPtr(Assembler::NotEqual, shapeAddr,
ImmGCPtr(scopeObj->as<NativeObject>().lastProperty()), failures);
}
Expand Down Expand Up @@ -4727,7 +4727,7 @@ BindNameIC::attachNonGlobal(JSContext* cx, HandleScript outerScript, IonScript*
// Guard on the shape of the scope chain.
Label failures;
attacher.branchNextStubOrLabel(masm, Assembler::NotEqual,
Address(scopeChainReg(), JSObject::offsetOfShape()),
Address(scopeChainReg(), ShapedObject::offsetOfShape()),
ImmGCPtr(scopeChain->as<NativeObject>().lastProperty()),
holder != scopeChain ? &failures : nullptr);

Expand Down
4 changes: 2 additions & 2 deletions js/src/jit/MacroAssembler-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -451,13 +451,13 @@ MacroAssembler::branchTestObjClass(Condition cond, Register obj, Register scratc
void
MacroAssembler::branchTestObjShape(Condition cond, Register obj, const Shape* shape, Label* label)
{
branchPtr(cond, Address(obj, JSObject::offsetOfShape()), ImmGCPtr(shape), label);
branchPtr(cond, Address(obj, ShapedObject::offsetOfShape()), ImmGCPtr(shape), label);
}

void
MacroAssembler::branchTestObjShape(Condition cond, Register obj, Register shape, Label* label)
{
branchPtr(cond, Address(obj, JSObject::offsetOfShape()), shape, label);
branchPtr(cond, Address(obj, ShapedObject::offsetOfShape()), shape, label);
}

void
Expand Down
2 changes: 1 addition & 1 deletion js/src/jit/MacroAssembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1086,7 +1086,7 @@ MacroAssembler::initGCThing(Register obj, Register temp, JSObject* templateObj,
storePtr(ImmGCPtr(templateObj->group()), Address(obj, JSObject::offsetOfGroup()));

if (Shape* shape = templateObj->maybeShape())
storePtr(ImmGCPtr(shape), Address(obj, JSObject::offsetOfShape()));
storePtr(ImmGCPtr(shape), Address(obj, ShapedObject::offsetOfShape()));

MOZ_ASSERT_IF(convertDoubleElements, templateObj->is<ArrayObject>());

Expand Down
2 changes: 1 addition & 1 deletion js/src/jit/MacroAssembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,7 @@ class MacroAssembler : public MacroAssemblerSpecific
void guardTypeSetMightBeIncomplete(TypeSet* types, Register obj, Register scratch, Label* label);

void loadObjShape(Register objReg, Register dest) {
loadPtr(Address(objReg, JSObject::offsetOfShape()), dest);
loadPtr(Address(objReg, ShapedObject::offsetOfShape()), dest);
}
void loadObjGroup(Register objReg, Register dest) {
loadPtr(Address(objReg, JSObject::offsetOfGroup()), dest);
Expand Down
2 changes: 1 addition & 1 deletion js/src/jit/SharedIC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2890,7 +2890,7 @@ ICGetProp_Primitive::Compiler::generateStubCode(MacroAssembler& masm)
masm.movePtr(ImmGCPtr(prototype_.get()), holderReg);

Address shapeAddr(ICStubReg, ICGetProp_Primitive::offsetOfProtoShape());
masm.loadPtr(Address(holderReg, JSObject::offsetOfShape()), scratchReg);
masm.loadPtr(Address(holderReg, ShapedObject::offsetOfShape()), scratchReg);
masm.branchPtr(Assembler::NotEqual, shapeAddr, scratchReg, &failure);

if (!isFixedSlot_)
Expand Down
2 changes: 1 addition & 1 deletion js/src/jit/arm/CodeGenerator-arm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1598,7 +1598,7 @@ CodeGeneratorARM::visitGuardShape(LGuardShape* guard)
Register obj = ToRegister(guard->input());
Register tmp = ToRegister(guard->tempInt());

masm.ma_ldr(DTRAddr(obj, DtrOffImm(JSObject::offsetOfShape())), tmp);
masm.ma_ldr(DTRAddr(obj, DtrOffImm(ShapedObject::offsetOfShape())), tmp);
masm.ma_cmp(tmp, ImmGCPtr(guard->mir()->shape()));

bailoutIf(Assembler::NotEqual, guard->snapshot());
Expand Down
2 changes: 1 addition & 1 deletion js/src/jit/mips-shared/CodeGenerator-mips-shared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1628,7 +1628,7 @@ CodeGeneratorMIPSShared::visitGuardShape(LGuardShape* guard)
Register obj = ToRegister(guard->input());
Register tmp = ToRegister(guard->tempInt());

masm.loadPtr(Address(obj, JSObject::offsetOfShape()), tmp);
masm.loadPtr(Address(obj, ShapedObject::offsetOfShape()), tmp);
bailoutCmpPtr(Assembler::NotEqual, tmp, ImmGCPtr(guard->mir()->shape()),
guard->snapshot());
}
Expand Down
2 changes: 1 addition & 1 deletion js/src/jit/x86-shared/CodeGenerator-x86-shared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2249,7 +2249,7 @@ void
CodeGeneratorX86Shared::visitGuardShape(LGuardShape* guard)
{
Register obj = ToRegister(guard->input());
masm.cmpPtr(Operand(obj, JSObject::offsetOfShape()), ImmGCPtr(guard->mir()->shape()));
masm.cmpPtr(Operand(obj, ShapedObject::offsetOfShape()), ImmGCPtr(guard->mir()->shape()));

bailoutIf(Assembler::NotEqual, guard->snapshot());
}
Expand Down
8 changes: 0 additions & 8 deletions js/src/jsobj.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,6 @@ class JSObject : public js::gc::Cell
js::HandleShape shape,
js::HandleObjectGroup group);

// Set the shape of an object. This pointer is valid for native objects and
// some non-native objects. After creating an object, the objects for which
// the shape pointer is invalid need to overwrite this pointer before a GC
// can occur.
inline void setInitialShapeMaybeNonNative(js::Shape* shape);
inline void setShapeMaybeNonNative(js::Shape* shape);

// Set the initial slots and elements of an object. These pointers are only
// valid for native objects, but during initialization are set for all
// objects. For non-native objects, these must not be dynamically allocated
Expand Down Expand Up @@ -569,7 +562,6 @@ class JSObject : public js::gc::Cell
/* JIT Accessors */

static size_t offsetOfGroup() { return offsetof(JSObject, group_); }
static size_t offsetOfShape() { return sizeof(JSObject); }

// Maximum size in bytes of a JSObject.
static const size_t MAX_BYTE_SIZE = 4 * sizeof(void*) + 16 * sizeof(JS::Value);
Expand Down
26 changes: 10 additions & 16 deletions js/src/jsobjinlines.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "jscompartmentinlines.h"
#include "jsgcinlines.h"

#include "vm/ShapedObject-inl.h"
#include "vm/TypeInference-inl.h"

namespace js {
Expand All @@ -49,9 +50,10 @@ MaybeConvertUnboxedObjectToNative(ExclusiveContext* cx, JSObject* obj)
inline js::Shape*
JSObject::maybeShape() const
{
if (is<js::UnboxedPlainObject>() || is<js::UnboxedArrayObject>())
if (!is<js::ShapedObject>())
return nullptr;
return *reinterpret_cast<js::Shape**>(uintptr_t(this) + offsetOfShape());

return as<js::ShapedObject>().shape();
}

inline js::Shape*
Expand Down Expand Up @@ -355,7 +357,12 @@ JSObject::create(js::ExclusiveContext* cx, js::gc::AllocKind kind, js::gc::Initi

obj->group_.init(group);

obj->setInitialShapeMaybeNonNative(shape);
// This function allocates normal objects and proxies and typed objects
// (all with shapes), *and* it allocates objects without shapes (various
// unboxed object classes). Setting shape is naturally only valid for the
// former class of objects.
if (obj->is<js::ShapedObject>())
obj->as<js::ShapedObject>().initShape(shape);

// Note: slots are created and assigned internally by Allocate<JSObject>.
obj->setInitialElementsMaybeNonNative(js::emptyObjectElements);
Expand Down Expand Up @@ -390,19 +397,6 @@ JSObject::create(js::ExclusiveContext* cx, js::gc::AllocKind kind, js::gc::Initi
return obj;
}

inline void
JSObject::setInitialShapeMaybeNonNative(js::Shape* shape)
{
static_cast<js::NativeObject*>(this)->shape_.init(shape);
}

inline void
JSObject::setShapeMaybeNonNative(js::Shape* shape)
{
MOZ_ASSERT(!is<js::UnboxedPlainObject>());
static_cast<js::NativeObject*>(this)->shape_ = shape;
}

inline void
JSObject::setInitialSlotsMaybeNonNative(js::HeapSlot* slots)
{
Expand Down
2 changes: 1 addition & 1 deletion js/src/jspropertytree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ Shape::fixupDictionaryShapeAfterMovingGC()
listp = &gc::Forwarded(next)->parent;
} else {
// listp points to the shape_ field of an object.
JSObject* last = reinterpret_cast<JSObject*>(uintptr_t(listp) - JSObject::offsetOfShape());
JSObject* last = reinterpret_cast<JSObject*>(uintptr_t(listp) - ShapedObject::offsetOfShape());
if (gc::IsForwarded(last))
listp = &gc::Forwarded(last)->as<NativeObject>().shape_;
}
Expand Down
2 changes: 1 addition & 1 deletion js/src/proxy/Proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@ ProxyObject::trace(JSTracer* trc, JSObject* obj)
{
ProxyObject* proxy = &obj->as<ProxyObject>();

TraceEdge(trc, &proxy->shape, "ProxyObject_shape");
TraceEdge(trc, &proxy->shape_, "ProxyObject_shape");

#ifdef DEBUG
if (trc->runtime()->gc.isStrictProxyCheckingEnabled() && proxy->is<WrapperObject>()) {
Expand Down
Loading

0 comments on commit 5211692

Please sign in to comment.