mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-12 02:31:41 +00:00
Backed out changeset 062226e8a2d2 (bug 1091015) for SM test failures.
This commit is contained in:
parent
aaced0941c
commit
52c9f5e3b8
@ -535,7 +535,7 @@ const Class SizedArrayTypeDescr::class_ = {
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
TypedObject::constructSized,
|
||||
OutlineTypedObject::constructSized,
|
||||
nullptr
|
||||
};
|
||||
|
||||
@ -641,7 +641,7 @@ ArrayMetaTypeDescr::create(JSContext *cx,
|
||||
int32_t size)
|
||||
{
|
||||
Rooted<T*> obj(cx);
|
||||
obj = NewObjectWithProto<T>(cx, arrayTypePrototype, nullptr, SingletonObject);
|
||||
obj = NewObjectWithProto<T>(cx, arrayTypePrototype, nullptr, TenuredObject);
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
@ -832,7 +832,7 @@ const Class StructTypeDescr::class_ = {
|
||||
nullptr, /* finalize */
|
||||
nullptr, /* call */
|
||||
nullptr, /* hasInstance */
|
||||
TypedObject::constructSized,
|
||||
OutlineTypedObject::constructSized,
|
||||
nullptr /* trace */
|
||||
};
|
||||
|
||||
@ -1011,7 +1011,7 @@ StructMetaTypeDescr::create(JSContext *cx,
|
||||
|
||||
Rooted<StructTypeDescr*> descr(cx);
|
||||
descr = NewObjectWithProto<StructTypeDescr>(cx, structTypePrototype, nullptr,
|
||||
SingletonObject);
|
||||
TenuredObject);
|
||||
if (!descr)
|
||||
return nullptr;
|
||||
|
||||
@ -1251,7 +1251,7 @@ DefineSimpleTypeDescr(JSContext *cx,
|
||||
return false;
|
||||
|
||||
Rooted<T*> descr(cx);
|
||||
descr = NewObjectWithProto<T>(cx, funcProto, global, SingletonObject);
|
||||
descr = NewObjectWithProto<T>(cx, funcProto, global, TenuredObject);
|
||||
if (!descr)
|
||||
return false;
|
||||
|
||||
@ -1562,13 +1562,12 @@ TypedObject::GetByteOffset(JSContext *cx, unsigned argc, Value *vp)
|
||||
/*static*/ OutlineTypedObject *
|
||||
OutlineTypedObject::createUnattached(JSContext *cx,
|
||||
HandleTypeDescr descr,
|
||||
int32_t length,
|
||||
gc::InitialHeap heap)
|
||||
int32_t length)
|
||||
{
|
||||
if (descr->opaque())
|
||||
return createUnattachedWithClass(cx, &OutlineOpaqueTypedObject::class_, descr, length, heap);
|
||||
return createUnattachedWithClass(cx, &OutlineOpaqueTypedObject::class_, descr, length);
|
||||
else
|
||||
return createUnattachedWithClass(cx, &OutlineTransparentTypedObject::class_, descr, length, heap);
|
||||
return createUnattachedWithClass(cx, &OutlineTransparentTypedObject::class_, descr, length);
|
||||
}
|
||||
|
||||
static JSObject *
|
||||
@ -1607,8 +1606,7 @@ OutlineTypedObject::setOwnerAndData(JSObject *owner, uint8_t *data)
|
||||
OutlineTypedObject::createUnattachedWithClass(JSContext *cx,
|
||||
const Class *clasp,
|
||||
HandleTypeDescr type,
|
||||
int32_t length,
|
||||
gc::InitialHeap heap)
|
||||
int32_t length)
|
||||
{
|
||||
MOZ_ASSERT(clasp == &OutlineTransparentTypedObject::class_ ||
|
||||
clasp == &OutlineOpaqueTypedObject::class_);
|
||||
@ -1618,8 +1616,7 @@ OutlineTypedObject::createUnattachedWithClass(JSContext *cx,
|
||||
return nullptr;
|
||||
|
||||
gc::AllocKind allocKind = allocKindForTypeDescriptor(type);
|
||||
NewObjectKind newKind = (heap == gc::TenuredHeap) ? MaybeSingletonObject : GenericObject;
|
||||
JSObject *obj = NewObjectWithClassProto(cx, clasp, proto, nullptr, allocKind, newKind);
|
||||
JSObject *obj = NewObjectWithClassProto(cx, clasp, proto, nullptr, allocKind);
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
@ -1710,19 +1707,19 @@ OutlineTypedObject::createDerived(JSContext *cx, HandleSizedTypeDescr type,
|
||||
}
|
||||
|
||||
/*static*/ TypedObject *
|
||||
TypedObject::createZeroed(JSContext *cx, HandleTypeDescr descr, int32_t length, gc::InitialHeap heap)
|
||||
TypedObject::createZeroed(JSContext *cx, HandleTypeDescr descr, int32_t length)
|
||||
{
|
||||
// If possible, create an object with inline data.
|
||||
if (descr->is<SizedTypeDescr>() &&
|
||||
(size_t) descr->as<SizedTypeDescr>().size() <= InlineTypedObject::MaximumSize)
|
||||
{
|
||||
InlineTypedObject *obj = InlineTypedObject::create(cx, descr, heap);
|
||||
InlineTypedObject *obj = InlineTypedObject::create(cx, descr);
|
||||
descr->as<SizedTypeDescr>().initInstances(cx->runtime(), obj->inlineTypedMem(), 1);
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Create unattached wrapper object.
|
||||
Rooted<OutlineTypedObject*> obj(cx, OutlineTypedObject::createUnattached(cx, descr, length, heap));
|
||||
Rooted<OutlineTypedObject*> obj(cx, OutlineTypedObject::createUnattached(cx, descr, length));
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
@ -2376,7 +2373,7 @@ OutlineTypedObject::neuter(void *newData)
|
||||
*/
|
||||
|
||||
/* static */ InlineTypedObject *
|
||||
InlineTypedObject::create(JSContext *cx, HandleTypeDescr descr, gc::InitialHeap heap)
|
||||
InlineTypedObject::create(JSContext *cx, HandleTypeDescr descr)
|
||||
{
|
||||
gc::AllocKind allocKind = allocKindForTypeDescriptor(descr);
|
||||
|
||||
@ -2388,27 +2385,13 @@ InlineTypedObject::create(JSContext *cx, HandleTypeDescr descr, gc::InitialHeap
|
||||
? &InlineOpaqueTypedObject::class_
|
||||
: &InlineTransparentTypedObject::class_;
|
||||
|
||||
NewObjectKind newKind = (heap == gc::TenuredHeap) ? MaybeSingletonObject : GenericObject;
|
||||
RootedObject obj(cx, NewObjectWithClassProto(cx, clasp, proto, nullptr, allocKind, newKind));
|
||||
RootedObject obj(cx, NewObjectWithClassProto(cx, clasp, proto, nullptr, allocKind));
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
return &obj->as<InlineTypedObject>();
|
||||
}
|
||||
|
||||
/* static */ InlineTypedObject *
|
||||
InlineTypedObject::createCopy(JSContext *cx, Handle<InlineTypedObject *> templateObject,
|
||||
gc::InitialHeap heap)
|
||||
{
|
||||
Rooted<TypeDescr *> descr(cx, &templateObject->typeDescr());
|
||||
InlineTypedObject *res = create(cx, descr, heap);
|
||||
if (!res)
|
||||
return nullptr;
|
||||
|
||||
memcpy(res->inlineTypedMem(), templateObject->inlineTypedMem(), templateObject->size());
|
||||
return res;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
InlineTypedObject::obj_trace(JSTracer *trc, JSObject *object)
|
||||
{
|
||||
|
@ -676,8 +676,7 @@ class TypedObject : public JSObject
|
||||
// Creates a new typed object whose memory is freshly allocated and
|
||||
// initialized with zeroes (or, in the case of references, an appropriate
|
||||
// default value).
|
||||
static TypedObject *createZeroed(JSContext *cx, HandleTypeDescr typeObj, int32_t length,
|
||||
gc::InitialHeap heap = gc::DefaultHeap);
|
||||
static TypedObject *createZeroed(JSContext *cx, HandleTypeDescr typeObj, int32_t length);
|
||||
|
||||
// User-accessible constructor (`new TypeDescriptor(...)`) used for sized
|
||||
// types. Note that the callee here is the type descriptor.
|
||||
@ -754,8 +753,7 @@ class OutlineTypedObject : public TypedObject
|
||||
static OutlineTypedObject *createUnattachedWithClass(JSContext *cx,
|
||||
const Class *clasp,
|
||||
HandleTypeDescr type,
|
||||
int32_t length,
|
||||
gc::InitialHeap heap = gc::DefaultHeap);
|
||||
int32_t length);
|
||||
|
||||
// Creates an unattached typed object or handle (depending on the
|
||||
// type parameter T). Note that it is only legal for unattached
|
||||
@ -766,7 +764,7 @@ class OutlineTypedObject : public TypedObject
|
||||
// - type: type object for resulting object
|
||||
// - length: 0 unless this is an array, otherwise the length
|
||||
static OutlineTypedObject *createUnattached(JSContext *cx, HandleTypeDescr type,
|
||||
int32_t length, gc::InitialHeap heap = gc::DefaultHeap);
|
||||
int32_t length);
|
||||
|
||||
// Creates a typedObj that aliases the memory pointed at by `owner`
|
||||
// at the given offset. The typedObj will be a handle iff type is a
|
||||
@ -812,8 +810,7 @@ class InlineTypedObject : public TypedObject
|
||||
uint8_t data_[1];
|
||||
|
||||
public:
|
||||
static const size_t MaximumSize =
|
||||
sizeof(NativeObject) - sizeof(TypedObject) + NativeObject::MAX_FIXED_SLOTS * sizeof(Value);
|
||||
static const size_t MaximumSize = NativeObject::MAX_FIXED_SLOTS * sizeof(Value);
|
||||
|
||||
static gc::AllocKind allocKindForTypeDescriptor(TypeDescr *descr) {
|
||||
size_t nbytes = descr->as<SizedTypeDescr>().size();
|
||||
@ -836,10 +833,7 @@ class InlineTypedObject : public TypedObject
|
||||
return offsetof(InlineTypedObject, data_);
|
||||
}
|
||||
|
||||
static InlineTypedObject *create(JSContext *cx, HandleTypeDescr descr,
|
||||
gc::InitialHeap heap = gc::DefaultHeap);
|
||||
static InlineTypedObject *createCopy(JSContext *cx, Handle<InlineTypedObject *> templateObject,
|
||||
gc::InitialHeap heap);
|
||||
static InlineTypedObject *create(JSContext *cx, HandleTypeDescr descr);
|
||||
};
|
||||
|
||||
// Class for a transparent typed object with inline data, which may have a
|
||||
|
@ -201,12 +201,6 @@ ICStub::trace(JSTracer *trc)
|
||||
MarkObject(trc, &callStub->templateObject(), "baseline-callnative-template");
|
||||
break;
|
||||
}
|
||||
case ICStub::Call_ClassHook: {
|
||||
ICCall_ClassHook *callStub = toCall_ClassHook();
|
||||
if (callStub->templateObject())
|
||||
MarkObject(trc, &callStub->templateObject(), "baseline-callclasshook-template");
|
||||
break;
|
||||
}
|
||||
case ICStub::Call_StringSplit: {
|
||||
ICCall_StringSplit *callStub = toCall_StringSplit();
|
||||
MarkObject(trc, &callStub->templateObject(), "baseline-callstringsplit-template");
|
||||
@ -710,7 +704,6 @@ ICStubCompiler::guardProfilingEnabled(MacroAssembler &masm, Register scratch, La
|
||||
MOZ_ASSERT(kind == ICStub::Call_Scripted ||
|
||||
kind == ICStub::Call_AnyScripted ||
|
||||
kind == ICStub::Call_Native ||
|
||||
kind == ICStub::Call_ClassHook ||
|
||||
kind == ICStub::Call_ScriptedApplyArray ||
|
||||
kind == ICStub::Call_ScriptedApplyArguments ||
|
||||
kind == ICStub::Call_ScriptedFunCall ||
|
||||
@ -8589,22 +8582,6 @@ GetTemplateObjectForNative(JSContext *cx, HandleScript script, jsbytecode *pc,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
GetTemplateObjectForClassHook(JSContext *cx, JSNative hook, CallArgs &args,
|
||||
MutableHandleObject templateObject)
|
||||
{
|
||||
if (hook == TypedObject::constructSized) {
|
||||
Rooted<TypeDescr *> descr(cx, &args.callee().as<TypeDescr>());
|
||||
JSObject *obj = TypedObject::createZeroed(cx, descr, 1, gc::TenuredHeap);
|
||||
if (!obj)
|
||||
return false;
|
||||
templateObject.set(obj);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsOptimizableCallStringSplit(Value callee, Value thisv, int argc, Value *args)
|
||||
{
|
||||
@ -8654,27 +8631,8 @@ TryAttachCallStub(JSContext *cx, ICCall_Fallback *stub, HandleScript script, jsb
|
||||
return true;
|
||||
|
||||
RootedObject obj(cx, &callee.toObject());
|
||||
if (!obj->is<JSFunction>()) {
|
||||
if (JSNative hook = constructing ? obj->constructHook() : obj->callHook()) {
|
||||
if (op != JSOP_FUNAPPLY && !isSpread && !useNewType) {
|
||||
RootedObject templateObject(cx);
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (!GetTemplateObjectForClassHook(cx, hook, args, &templateObject))
|
||||
return false;
|
||||
|
||||
JitSpew(JitSpew_BaselineIC, " Generating Call_ClassHook stub");
|
||||
ICCall_ClassHook::Compiler compiler(cx, stub->fallbackMonitorStub()->firstMonitorStub(),
|
||||
obj->getClass(), hook, templateObject, constructing);
|
||||
ICStub *newStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
if (!newStub)
|
||||
return false;
|
||||
|
||||
stub->addNewStub(newStub);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (!obj->is<JSFunction>())
|
||||
return true;
|
||||
}
|
||||
|
||||
RootedFunction fun(cx, &obj->as<JSFunction>());
|
||||
|
||||
@ -9852,95 +9810,6 @@ ICCall_Native::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ICCall_ClassHook::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
Label failure;
|
||||
GeneralRegisterSet regs(availableGeneralRegs(0));
|
||||
|
||||
Register argcReg = R0.scratchReg();
|
||||
regs.take(argcReg);
|
||||
regs.takeUnchecked(BaselineTailCallReg);
|
||||
|
||||
// Load the callee in R1.
|
||||
BaseIndex calleeSlot(BaselineStackReg, argcReg, TimesEight, ICStackValueOffset + sizeof(Value));
|
||||
masm.loadValue(calleeSlot, R1);
|
||||
regs.take(R1);
|
||||
|
||||
masm.branchTestObject(Assembler::NotEqual, R1, &failure);
|
||||
|
||||
// Ensure the callee's class matches the one in this stub.
|
||||
Register callee = masm.extractObject(R1, ExtractTemp0);
|
||||
Register scratch = regs.takeAny();
|
||||
masm.loadObjClass(callee, scratch);
|
||||
masm.branchPtr(Assembler::NotEqual,
|
||||
Address(BaselineStubReg, ICCall_ClassHook::offsetOfClass()),
|
||||
scratch, &failure);
|
||||
|
||||
regs.add(R1);
|
||||
regs.takeUnchecked(callee);
|
||||
|
||||
// Push a stub frame so that we can perform a non-tail call.
|
||||
// Note that this leaves the return address in TailCallReg.
|
||||
enterStubFrame(masm, regs.getAny());
|
||||
|
||||
pushCallArguments(masm, regs, argcReg);
|
||||
|
||||
if (isConstructing_) {
|
||||
// Stack looks like: [ ..., Arg0Val, ThisVal, CalleeVal ]
|
||||
// Replace ThisVal with MagicValue(JS_IS_CONSTRUCTING)
|
||||
masm.storeValue(MagicValue(JS_IS_CONSTRUCTING), Address(BaselineStackReg, sizeof(Value)));
|
||||
}
|
||||
|
||||
masm.checkStackAlignment();
|
||||
|
||||
// Native functions have the signature:
|
||||
//
|
||||
// bool (*)(JSContext *, unsigned, Value *vp)
|
||||
//
|
||||
// Where vp[0] is space for callee/return value, vp[1] is |this|, and vp[2] onward
|
||||
// are the function arguments.
|
||||
|
||||
// Initialize vp.
|
||||
Register vpReg = regs.takeAny();
|
||||
masm.movePtr(StackPointer, vpReg);
|
||||
|
||||
// Construct a native exit frame.
|
||||
masm.push(argcReg);
|
||||
|
||||
EmitCreateStubFrameDescriptor(masm, scratch);
|
||||
masm.push(scratch);
|
||||
masm.push(BaselineTailCallReg);
|
||||
masm.enterFakeExitFrame(IonNativeExitFrameLayout::Token());
|
||||
|
||||
// If needed, update SPS Profiler frame entry. At this point, BaselineTailCallReg
|
||||
// and scratch can be clobbered.
|
||||
emitProfilingUpdate(masm, BaselineTailCallReg, scratch, ICCall_Native::offsetOfPCOffset());
|
||||
|
||||
// Execute call.
|
||||
masm.setupUnalignedABICall(3, scratch);
|
||||
masm.loadJSContext(scratch);
|
||||
masm.passABIArg(scratch);
|
||||
masm.passABIArg(argcReg);
|
||||
masm.passABIArg(vpReg);
|
||||
masm.callWithABI(Address(BaselineStubReg, ICCall_ClassHook::offsetOfNative()));
|
||||
|
||||
// Test for failure.
|
||||
masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel());
|
||||
|
||||
// Load the return value into R0.
|
||||
masm.loadValue(Address(StackPointer, IonNativeExitFrameLayout::offsetOfResult()), R0);
|
||||
|
||||
leaveStubFrame(masm);
|
||||
|
||||
// Enter type monitor IC to type-check result.
|
||||
EmitEnterTypeMonitorIC(masm);
|
||||
|
||||
masm.bind(&failure);
|
||||
EmitStubGuardFailure(masm);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ICCall_ScriptedApplyArray::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
@ -11288,21 +11157,6 @@ ICCall_Native::Clone(JSContext *cx, ICStubSpace *space, ICStub *firstMonitorStub
|
||||
other.pcOffset_);
|
||||
}
|
||||
|
||||
ICCall_ClassHook::ICCall_ClassHook(JitCode *stubCode, ICStub *firstMonitorStub,
|
||||
const Class *clasp, Native native, HandleObject templateObject)
|
||||
: ICMonitoredStub(ICStub::Call_ClassHook, stubCode, firstMonitorStub),
|
||||
clasp_(clasp),
|
||||
native_(JS_FUNC_TO_DATA_PTR(void *, native)),
|
||||
templateObject_(templateObject)
|
||||
{
|
||||
#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR)
|
||||
// The simulator requires VM calls to be redirected to a special swi
|
||||
// instruction to handle them. To make this work, we store the redirected
|
||||
// pointer in the stub.
|
||||
native_ = Simulator::RedirectNativeFunction(native_, Args_General3);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* static */ ICCall_ScriptedApplyArray *
|
||||
ICCall_ScriptedApplyArray::Clone(JSContext *, ICStubSpace *space, ICStub *firstMonitorStub,
|
||||
ICCall_ScriptedApplyArray &other)
|
||||
|
@ -375,7 +375,6 @@ class ICEntry
|
||||
_(Call_Scripted) \
|
||||
_(Call_AnyScripted) \
|
||||
_(Call_Native) \
|
||||
_(Call_ClassHook) \
|
||||
_(Call_ScriptedApplyArray) \
|
||||
_(Call_ScriptedApplyArguments) \
|
||||
_(Call_ScriptedFunCall) \
|
||||
@ -791,7 +790,6 @@ class ICStub
|
||||
case Call_Scripted:
|
||||
case Call_AnyScripted:
|
||||
case Call_Native:
|
||||
case Call_ClassHook:
|
||||
case Call_ScriptedApplyArray:
|
||||
case Call_ScriptedApplyArguments:
|
||||
case Call_ScriptedFunCall:
|
||||
@ -5899,80 +5897,6 @@ class ICCall_Native : public ICMonitoredStub
|
||||
};
|
||||
};
|
||||
|
||||
class ICCall_ClassHook : public ICMonitoredStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
protected:
|
||||
const Class *clasp_;
|
||||
void *native_;
|
||||
HeapPtrObject templateObject_;
|
||||
|
||||
ICCall_ClassHook(JitCode *stubCode, ICStub *firstMonitorStub,
|
||||
const Class *clasp, Native native, HandleObject templateObject);
|
||||
|
||||
public:
|
||||
static inline ICCall_ClassHook *New(ICStubSpace *space,
|
||||
JitCode *code, ICStub *firstMonitorStub,
|
||||
const Class *clasp, Native native,
|
||||
HandleObject templateObject)
|
||||
{
|
||||
if (!code)
|
||||
return nullptr;
|
||||
return space->allocate<ICCall_ClassHook>(code, firstMonitorStub,
|
||||
clasp, native, templateObject);
|
||||
}
|
||||
|
||||
const Class *clasp() {
|
||||
return clasp_;
|
||||
}
|
||||
void *native() {
|
||||
return native_;
|
||||
}
|
||||
HeapPtrObject &templateObject() {
|
||||
return templateObject_;
|
||||
}
|
||||
|
||||
static size_t offsetOfClass() {
|
||||
return offsetof(ICCall_ClassHook, clasp_);
|
||||
}
|
||||
static size_t offsetOfNative() {
|
||||
return offsetof(ICCall_ClassHook, native_);
|
||||
}
|
||||
|
||||
// Compiler for this stub kind.
|
||||
class Compiler : public ICCallStubCompiler {
|
||||
protected:
|
||||
ICStub *firstMonitorStub_;
|
||||
bool isConstructing_;
|
||||
const Class *clasp_;
|
||||
Native native_;
|
||||
RootedObject templateObject_;
|
||||
bool generateStubCode(MacroAssembler &masm);
|
||||
|
||||
virtual int32_t getKey() const {
|
||||
return static_cast<int32_t>(kind) | (static_cast<int32_t>(isConstructing_) << 16);
|
||||
}
|
||||
|
||||
public:
|
||||
Compiler(JSContext *cx, ICStub *firstMonitorStub,
|
||||
const Class *clasp, Native native, HandleObject templateObject,
|
||||
bool isConstructing)
|
||||
: ICCallStubCompiler(cx, ICStub::Call_ClassHook),
|
||||
firstMonitorStub_(firstMonitorStub),
|
||||
isConstructing_(isConstructing),
|
||||
clasp_(clasp),
|
||||
native_(native),
|
||||
templateObject_(cx, templateObject)
|
||||
{ }
|
||||
|
||||
ICStub *getStub(ICStubSpace *space) {
|
||||
return ICCall_ClassHook::New(space, getStubCode(), firstMonitorStub_,
|
||||
clasp_, native_, templateObject_);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class ICCall_ScriptedApplyArray : public ICMonitoredStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
@ -455,21 +455,6 @@ BaselineInspector::getTemplateObjectForNative(jsbytecode *pc, Native native)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
BaselineInspector::getTemplateObjectForClassHook(jsbytecode *pc, const Class *clasp)
|
||||
{
|
||||
if (!hasBaselineScript())
|
||||
return nullptr;
|
||||
|
||||
const ICEntry &entry = icEntryFromPC(pc);
|
||||
for (ICStub *stub = entry.firstStub(); stub; stub = stub->next()) {
|
||||
if (stub->isCall_ClassHook() && stub->toCall_ClassHook()->clasp() == clasp)
|
||||
return stub->toCall_ClassHook()->templateObject();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DeclEnvObject *
|
||||
BaselineInspector::templateDeclEnvObject()
|
||||
{
|
||||
|
@ -111,7 +111,6 @@ class BaselineInspector
|
||||
|
||||
NativeObject *getTemplateObject(jsbytecode *pc);
|
||||
NativeObject *getTemplateObjectForNative(jsbytecode *pc, Native native);
|
||||
JSObject *getTemplateObjectForClassHook(jsbytecode *pc, const Class *clasp);
|
||||
|
||||
DeclEnvObject *templateDeclEnvObject();
|
||||
CallObject *templateCallObject();
|
||||
|
@ -4452,31 +4452,6 @@ CodeGenerator::visitOutOfLineNewObject(OutOfLineNewObject *ool)
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef InlineTypedObject *(*NewTypedObjectFn)(JSContext *, Handle<InlineTypedObject *>, gc::InitialHeap);
|
||||
static const VMFunction NewTypedObjectInfo =
|
||||
FunctionInfo<NewTypedObjectFn>(InlineTypedObject::createCopy);
|
||||
|
||||
bool
|
||||
CodeGenerator::visitNewTypedObject(LNewTypedObject *lir)
|
||||
{
|
||||
Register object = ToRegister(lir->output());
|
||||
Register temp = ToRegister(lir->temp());
|
||||
InlineTypedObject *templateObject = lir->mir()->templateObject();
|
||||
gc::InitialHeap initialHeap = lir->mir()->initialHeap();
|
||||
|
||||
OutOfLineCode *ool = oolCallVM(NewTypedObjectInfo, lir,
|
||||
(ArgList(), ImmGCPtr(templateObject), Imm32(initialHeap)),
|
||||
StoreRegisterTo(object));
|
||||
if (!ool)
|
||||
return false;
|
||||
|
||||
gc::AllocKind allocKind = templateObject->asTenured().getAllocKind();
|
||||
masm.createGCObject(object, temp, templateObject, initialHeap, ool->entry());
|
||||
|
||||
masm.bind(ool->rejoin());
|
||||
return true;
|
||||
}
|
||||
|
||||
typedef js::DeclEnvObject *(*NewDeclEnvObjectFn)(JSContext *, HandleFunction, gc::InitialHeap);
|
||||
static const VMFunction NewDeclEnvObjectInfo =
|
||||
FunctionInfo<NewDeclEnvObjectFn>(DeclEnvObject::createTemplateObject);
|
||||
|
@ -155,7 +155,6 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
bool visitNewObjectVMCall(LNewObject *lir);
|
||||
bool visitNewObject(LNewObject *lir);
|
||||
bool visitOutOfLineNewObject(OutOfLineNewObject *ool);
|
||||
bool visitNewTypedObject(LNewTypedObject *lir);
|
||||
bool visitNewDeclEnvObject(LNewDeclEnvObject *lir);
|
||||
bool visitNewCallObject(LNewCallObject *lir);
|
||||
bool visitNewSingletonCallObject(LNewSingletonCallObject *lir);
|
||||
|
@ -292,7 +292,14 @@ IonBuilder::getPolyCallTargets(types::TemporaryTypeSet *calleeTypes, bool constr
|
||||
return false;
|
||||
for(unsigned i = 0; i < objCount; i++) {
|
||||
JSObject *obj = calleeTypes->getSingleObject(i);
|
||||
if (!obj) {
|
||||
JSFunction *fun;
|
||||
if (obj) {
|
||||
if (!obj->is<JSFunction>()) {
|
||||
targets.clear();
|
||||
return true;
|
||||
}
|
||||
fun = &obj->as<JSFunction>();
|
||||
} else {
|
||||
types::TypeObject *typeObj = calleeTypes->getTypeObject(i);
|
||||
MOZ_ASSERT(typeObj);
|
||||
if (!typeObj->interpretedFunction) {
|
||||
@ -300,19 +307,19 @@ IonBuilder::getPolyCallTargets(types::TemporaryTypeSet *calleeTypes, bool constr
|
||||
return true;
|
||||
}
|
||||
|
||||
obj = typeObj->interpretedFunction;
|
||||
fun = typeObj->interpretedFunction;
|
||||
*gotLambda = true;
|
||||
}
|
||||
|
||||
// Don't optimize if the callee is not callable or constructable per
|
||||
// the manner it is being invoked, so that CallKnown does not have to
|
||||
// handle these cases (they will always throw).
|
||||
if (constructing ? !obj->isConstructor() : !obj->isCallable()) {
|
||||
// Don't optimize if we're constructing and the callee is not a
|
||||
// constructor, so that CallKnown does not have to handle this case
|
||||
// (it should always throw).
|
||||
if (constructing && !fun->isInterpretedConstructor() && !fun->isNativeConstructor()) {
|
||||
targets.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
DebugOnly<bool> appendOk = targets.append(obj);
|
||||
DebugOnly<bool> appendOk = targets.append(fun);
|
||||
MOZ_ASSERT(appendOk);
|
||||
}
|
||||
|
||||
@ -4410,18 +4417,12 @@ IonBuilder::patchInlinedReturns(CallInfo &callInfo, MIRGraphReturns &returns, MB
|
||||
}
|
||||
|
||||
IonBuilder::InliningDecision
|
||||
IonBuilder::makeInliningDecision(JSObject *targetArg, CallInfo &callInfo)
|
||||
IonBuilder::makeInliningDecision(JSFunction *target, CallInfo &callInfo)
|
||||
{
|
||||
// When there is no target, inlining is impossible.
|
||||
if (targetArg == nullptr)
|
||||
if (target == nullptr)
|
||||
return InliningDecision_DontInline;
|
||||
|
||||
// Inlining non-function targets is handled by inlineNonFunctionCall().
|
||||
if (!targetArg->is<JSFunction>())
|
||||
return InliningDecision_Inline;
|
||||
|
||||
JSFunction *target = &targetArg->as<JSFunction>();
|
||||
|
||||
// Never inline during the arguments usage analysis.
|
||||
if (info().executionMode() == ArgumentsUsageAnalysis)
|
||||
return InliningDecision_DontInline;
|
||||
@ -4498,7 +4499,7 @@ IonBuilder::selectInliningTargets(ObjectVector &targets, CallInfo &callInfo, Boo
|
||||
return true;
|
||||
|
||||
for (size_t i = 0; i < targets.length(); i++) {
|
||||
JSObject *target = targets[i];
|
||||
JSFunction *target = &targets[i]->as<JSFunction>();
|
||||
bool inlineable;
|
||||
InliningDecision decision = makeInliningDecision(target, callInfo);
|
||||
switch (decision) {
|
||||
@ -4515,16 +4516,11 @@ IonBuilder::selectInliningTargets(ObjectVector &targets, CallInfo &callInfo, Boo
|
||||
MOZ_CRASH("Unhandled InliningDecision value!");
|
||||
}
|
||||
|
||||
if (target->is<JSFunction>()) {
|
||||
// Enforce a maximum inlined bytecode limit at the callsite.
|
||||
if (inlineable && target->as<JSFunction>().isInterpreted()) {
|
||||
totalSize += target->as<JSFunction>().nonLazyScript()->length();
|
||||
if (totalSize > optimizationInfo().inlineMaxTotalBytecodeLength())
|
||||
inlineable = false;
|
||||
}
|
||||
} else {
|
||||
// Non-function targets are not supported by polymorphic inlining.
|
||||
inlineable = false;
|
||||
// Enforce a maximum inlined bytecode limit at the callsite.
|
||||
if (inlineable && target->isInterpreted()) {
|
||||
totalSize += target->nonLazyScript()->length();
|
||||
if (totalSize > optimizationInfo().inlineMaxTotalBytecodeLength())
|
||||
inlineable = false;
|
||||
}
|
||||
|
||||
choiceSet.append(inlineable);
|
||||
@ -4652,12 +4648,9 @@ IonBuilder::getInlineableGetPropertyCache(CallInfo &callInfo)
|
||||
}
|
||||
|
||||
IonBuilder::InliningStatus
|
||||
IonBuilder::inlineSingleCall(CallInfo &callInfo, JSObject *targetArg)
|
||||
IonBuilder::inlineSingleCall(CallInfo &callInfo, JSFunction *target)
|
||||
{
|
||||
if (!targetArg->is<JSFunction>())
|
||||
return inlineNonFunctionCall(callInfo, targetArg);
|
||||
|
||||
JSFunction *target = &targetArg->as<JSFunction>();
|
||||
// Expects formals to be popped and wrapped.
|
||||
if (target->isNative())
|
||||
return inlineNativeCall(callInfo, target);
|
||||
|
||||
@ -4682,7 +4675,7 @@ IonBuilder::inlineCallsite(ObjectVector &targets, ObjectVector &originals,
|
||||
// Inline single targets -- unless they derive from a cache, in which case
|
||||
// avoiding the cache and guarding is still faster.
|
||||
if (!propCache.get() && targets.length() == 1) {
|
||||
JSObject *target = targets[0];
|
||||
JSFunction *target = &targets[0]->as<JSFunction>();
|
||||
InliningDecision decision = makeInliningDecision(target, callInfo);
|
||||
switch (decision) {
|
||||
case InliningDecision_Error:
|
||||
@ -5487,19 +5480,14 @@ IonBuilder::jsop_call(uint32_t argc, bool constructing)
|
||||
bool hasClones = false;
|
||||
ObjectVector targets(alloc());
|
||||
for (uint32_t i = 0; i < originals.length(); i++) {
|
||||
JSObject *obj = originals[i];
|
||||
if (obj->is<JSFunction>()) {
|
||||
JSFunction *fun = &obj->as<JSFunction>();
|
||||
if (fun->hasScript() && fun->nonLazyScript()->shouldCloneAtCallsite()) {
|
||||
if (JSFunction *clone = ExistingCloneFunctionAtCallsite(compartment->callsiteClones(),
|
||||
fun, script(), pc))
|
||||
{
|
||||
obj = clone;
|
||||
hasClones = true;
|
||||
}
|
||||
JSFunction *fun = &originals[i]->as<JSFunction>();
|
||||
if (fun->hasScript() && fun->nonLazyScript()->shouldCloneAtCallsite()) {
|
||||
if (JSFunction *clone = ExistingCloneFunctionAtCallsite(compartment->callsiteClones(), fun, script(), pc)) {
|
||||
fun = clone;
|
||||
hasClones = true;
|
||||
}
|
||||
}
|
||||
if (!targets.append(obj))
|
||||
if (!targets.append(fun))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5516,7 +5504,7 @@ IonBuilder::jsop_call(uint32_t argc, bool constructing)
|
||||
|
||||
// No inline, just make the call.
|
||||
JSFunction *target = nullptr;
|
||||
if (targets.length() == 1 && targets[0]->is<JSFunction>())
|
||||
if (targets.length() == 1)
|
||||
target = &targets[0]->as<JSFunction>();
|
||||
|
||||
if (target && status == InliningStatus_WarmUpCountTooLow) {
|
||||
|
@ -676,7 +676,7 @@ class IonBuilder
|
||||
|
||||
// Oracles.
|
||||
InliningDecision canInlineTarget(JSFunction *target, CallInfo &callInfo);
|
||||
InliningDecision makeInliningDecision(JSObject *target, CallInfo &callInfo);
|
||||
InliningDecision makeInliningDecision(JSFunction *target, CallInfo &callInfo);
|
||||
bool selectInliningTargets(ObjectVector &targets, CallInfo &callInfo,
|
||||
BoolVector &choiceSet, uint32_t *numInlineable);
|
||||
|
||||
@ -746,12 +746,11 @@ class IonBuilder
|
||||
// ForkJoin intrinsics
|
||||
InliningStatus inlineForkJoinGetSlice(CallInfo &callInfo);
|
||||
|
||||
// TypedObject intrinsics and natives.
|
||||
// TypedObject intrinsics.
|
||||
InliningStatus inlineObjectIsTypeDescr(CallInfo &callInfo);
|
||||
InliningStatus inlineSetTypedObjectOffset(CallInfo &callInfo);
|
||||
bool elementAccessIsTypedObjectArrayOfScalarType(MDefinition* obj, MDefinition* id,
|
||||
ScalarTypeDescr::Type *arrayType);
|
||||
InliningStatus inlineConstructTypedObject(CallInfo &callInfo, SizedTypeDescr *target);
|
||||
|
||||
// Utility intrinsics.
|
||||
InliningStatus inlineIsCallable(CallInfo &callInfo);
|
||||
@ -778,9 +777,8 @@ class IonBuilder
|
||||
// Main inlining functions
|
||||
InliningStatus inlineNativeCall(CallInfo &callInfo, JSFunction *target);
|
||||
InliningStatus inlineNativeGetter(CallInfo &callInfo, JSFunction *target);
|
||||
InliningStatus inlineNonFunctionCall(CallInfo &callInfo, JSObject *target);
|
||||
bool inlineScriptedCall(CallInfo &callInfo, JSFunction *target);
|
||||
InliningStatus inlineSingleCall(CallInfo &callInfo, JSObject *target);
|
||||
InliningStatus inlineSingleCall(CallInfo &callInfo, JSFunction *target);
|
||||
|
||||
// Call functions
|
||||
InliningStatus inlineCallsite(ObjectVector &targets, ObjectVector &originals,
|
||||
|
@ -787,22 +787,18 @@ MacroAssembler::newGCThing(Register result, Register temp, NativeObject *templat
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::createGCObject(Register obj, Register temp, JSObject *templateObj,
|
||||
MacroAssembler::createGCObject(Register obj, Register temp, NativeObject *templateObj,
|
||||
gc::InitialHeap initialHeap, Label *fail, bool initFixedSlots)
|
||||
{
|
||||
uint32_t nDynamicSlots = templateObj->numDynamicSlots();
|
||||
gc::AllocKind allocKind = templateObj->asTenured().getAllocKind();
|
||||
MOZ_ASSERT(allocKind >= gc::FINALIZE_OBJECT0 && allocKind <= gc::FINALIZE_OBJECT_LAST);
|
||||
|
||||
uint32_t nDynamicSlots = 0;
|
||||
if (templateObj->isNative()) {
|
||||
nDynamicSlots = templateObj->as<NativeObject>().numDynamicSlots();
|
||||
|
||||
// Arrays with copy on write elements do not need fixed space for an
|
||||
// elements header. The template object, which owns the original
|
||||
// elements, might have another allocation kind.
|
||||
if (templateObj->as<NativeObject>().denseElementsAreCopyOnWrite())
|
||||
allocKind = gc::FINALIZE_OBJECT0_BACKGROUND;
|
||||
}
|
||||
// Arrays with copy on write elements do not need fixed space for an
|
||||
// elements header. The template object, which owns the original elements,
|
||||
// might have another allocation kind.
|
||||
if (templateObj->denseElementsAreCopyOnWrite())
|
||||
allocKind = gc::FINALIZE_OBJECT0_BACKGROUND;
|
||||
|
||||
allocateObject(obj, temp, allocKind, nDynamicSlots, initialHeap, fail);
|
||||
initGCThing(obj, temp, templateObj, initFixedSlots);
|
||||
@ -1034,73 +1030,54 @@ MacroAssembler::initGCSlots(Register obj, Register slots, NativeObject *template
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssembler::initGCThing(Register obj, Register slots, JSObject *templateObj,
|
||||
MacroAssembler::initGCThing(Register obj, Register slots, NativeObject *templateObj,
|
||||
bool initFixedSlots)
|
||||
{
|
||||
// Fast initialization of an empty object returned by allocateObject().
|
||||
|
||||
MOZ_ASSERT_IF(!templateObj->denseElementsAreCopyOnWrite(), !templateObj->hasDynamicElements());
|
||||
|
||||
storePtr(ImmGCPtr(templateObj->lastProperty()), Address(obj, JSObject::offsetOfShape()));
|
||||
storePtr(ImmGCPtr(templateObj->type()), Address(obj, JSObject::offsetOfType()));
|
||||
if (templateObj->hasDynamicSlots())
|
||||
storePtr(slots, Address(obj, NativeObject::offsetOfSlots()));
|
||||
else
|
||||
storePtr(ImmPtr(nullptr), Address(obj, NativeObject::offsetOfSlots()));
|
||||
|
||||
if (templateObj->isNative()) {
|
||||
NativeObject *ntemplate = &templateObj->as<NativeObject>();
|
||||
MOZ_ASSERT_IF(!ntemplate->denseElementsAreCopyOnWrite(), !ntemplate->hasDynamicElements());
|
||||
if (templateObj->denseElementsAreCopyOnWrite()) {
|
||||
storePtr(ImmPtr((const Value *) templateObj->getDenseElements()),
|
||||
Address(obj, NativeObject::offsetOfElements()));
|
||||
} else if (templateObj->is<ArrayObject>()) {
|
||||
Register temp = slots;
|
||||
MOZ_ASSERT(!templateObj->getDenseInitializedLength());
|
||||
|
||||
if (ntemplate->hasDynamicSlots())
|
||||
storePtr(slots, Address(obj, NativeObject::offsetOfSlots()));
|
||||
else
|
||||
storePtr(ImmPtr(nullptr), Address(obj, NativeObject::offsetOfSlots()));
|
||||
int elementsOffset = NativeObject::offsetOfFixedElements();
|
||||
|
||||
if (ntemplate->denseElementsAreCopyOnWrite()) {
|
||||
storePtr(ImmPtr((const Value *) ntemplate->getDenseElements()),
|
||||
Address(obj, NativeObject::offsetOfElements()));
|
||||
} else if (ntemplate->is<ArrayObject>()) {
|
||||
Register temp = slots;
|
||||
MOZ_ASSERT(!ntemplate->getDenseInitializedLength());
|
||||
computeEffectiveAddress(Address(obj, elementsOffset), temp);
|
||||
storePtr(temp, Address(obj, NativeObject::offsetOfElements()));
|
||||
|
||||
int elementsOffset = NativeObject::offsetOfFixedElements();
|
||||
|
||||
computeEffectiveAddress(Address(obj, elementsOffset), temp);
|
||||
storePtr(temp, Address(obj, NativeObject::offsetOfElements()));
|
||||
|
||||
// Fill in the elements header.
|
||||
store32(Imm32(ntemplate->getDenseCapacity()),
|
||||
Address(obj, elementsOffset + ObjectElements::offsetOfCapacity()));
|
||||
store32(Imm32(ntemplate->getDenseInitializedLength()),
|
||||
Address(obj, elementsOffset + ObjectElements::offsetOfInitializedLength()));
|
||||
store32(Imm32(ntemplate->as<ArrayObject>().length()),
|
||||
Address(obj, elementsOffset + ObjectElements::offsetOfLength()));
|
||||
store32(Imm32(ntemplate->shouldConvertDoubleElements()
|
||||
? ObjectElements::CONVERT_DOUBLE_ELEMENTS
|
||||
: 0),
|
||||
Address(obj, elementsOffset + ObjectElements::offsetOfFlags()));
|
||||
MOZ_ASSERT(!ntemplate->hasPrivate());
|
||||
} else {
|
||||
storePtr(ImmPtr(emptyObjectElements), Address(obj, NativeObject::offsetOfElements()));
|
||||
|
||||
initGCSlots(obj, slots, ntemplate, initFixedSlots);
|
||||
|
||||
if (ntemplate->hasPrivate()) {
|
||||
uint32_t nfixed = ntemplate->numFixedSlots();
|
||||
storePtr(ImmPtr(ntemplate->getPrivate()),
|
||||
Address(obj, NativeObject::getPrivateDataOffset(nfixed)));
|
||||
}
|
||||
}
|
||||
} else if (templateObj->is<InlineTypedObject>()) {
|
||||
InlineTypedObject *ntemplate = &templateObj->as<InlineTypedObject>();
|
||||
|
||||
// Memcpy the contents of the template object to the new object.
|
||||
size_t nbytes = ntemplate->size();
|
||||
size_t offset = 0;
|
||||
while (nbytes) {
|
||||
uintptr_t value = *(uintptr_t *)(ntemplate->inlineTypedMem() + offset);
|
||||
storePtr(ImmWord(value),
|
||||
Address(obj, InlineTypedObject::offsetOfDataStart() + offset));
|
||||
nbytes = (nbytes < sizeof(uintptr_t)) ? 0 : nbytes - sizeof(uintptr_t);
|
||||
offset += sizeof(uintptr_t);
|
||||
}
|
||||
// Fill in the elements header.
|
||||
store32(Imm32(templateObj->getDenseCapacity()),
|
||||
Address(obj, elementsOffset + ObjectElements::offsetOfCapacity()));
|
||||
store32(Imm32(templateObj->getDenseInitializedLength()),
|
||||
Address(obj, elementsOffset + ObjectElements::offsetOfInitializedLength()));
|
||||
store32(Imm32(templateObj->as<ArrayObject>().length()),
|
||||
Address(obj, elementsOffset + ObjectElements::offsetOfLength()));
|
||||
store32(Imm32(templateObj->shouldConvertDoubleElements()
|
||||
? ObjectElements::CONVERT_DOUBLE_ELEMENTS
|
||||
: 0),
|
||||
Address(obj, elementsOffset + ObjectElements::offsetOfFlags()));
|
||||
MOZ_ASSERT(!templateObj->hasPrivate());
|
||||
} else {
|
||||
MOZ_CRASH("Unknown object");
|
||||
storePtr(ImmPtr(emptyObjectElements), Address(obj, NativeObject::offsetOfElements()));
|
||||
|
||||
initGCSlots(obj, slots, templateObj, initFixedSlots);
|
||||
|
||||
if (templateObj->hasPrivate()) {
|
||||
uint32_t nfixed = templateObj->numFixedSlots();
|
||||
storePtr(ImmPtr(templateObj->getPrivate()),
|
||||
Address(obj, NativeObject::getPrivateDataOffset(nfixed)));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JS_GC_TRACE
|
||||
|
@ -816,12 +816,12 @@ class MacroAssembler : public MacroAssemblerSpecific
|
||||
public:
|
||||
void callMallocStub(size_t nbytes, Register result, Label *fail);
|
||||
void callFreeStub(Register slots);
|
||||
void createGCObject(Register result, Register temp, JSObject *templateObj,
|
||||
void createGCObject(Register result, Register temp, NativeObject *templateObj,
|
||||
gc::InitialHeap initialHeap, Label *fail, bool initFixedSlots = true);
|
||||
|
||||
void newGCThing(Register result, Register temp, NativeObject *templateObj,
|
||||
gc::InitialHeap initialHeap, Label *fail);
|
||||
void initGCThing(Register obj, Register temp, JSObject *templateObj,
|
||||
void initGCThing(Register obj, Register temp, NativeObject *templateObj,
|
||||
bool initFixedSlots = true);
|
||||
|
||||
void newGCString(Register result, Register temp, Label *fail);
|
||||
|
@ -730,24 +730,6 @@ class LNewObject : public LInstructionHelper<1, 0, 1>
|
||||
}
|
||||
};
|
||||
|
||||
class LNewTypedObject : public LInstructionHelper<1, 0, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(NewTypedObject)
|
||||
|
||||
explicit LNewTypedObject(const LDefinition &temp) {
|
||||
setTemp(0, temp);
|
||||
}
|
||||
|
||||
const LDefinition *temp() {
|
||||
return getTemp(0);
|
||||
}
|
||||
|
||||
MNewTypedObject *mir() const {
|
||||
return mir_->toNewTypedObject();
|
||||
}
|
||||
};
|
||||
|
||||
class LNewPar : public LInstructionHelper<1, 1, 2>
|
||||
{
|
||||
public:
|
||||
|
@ -48,7 +48,6 @@
|
||||
_(NewArrayCopyOnWrite) \
|
||||
_(ArraySplice) \
|
||||
_(NewObject) \
|
||||
_(NewTypedObject) \
|
||||
_(NewDeclEnvObject) \
|
||||
_(NewCallObject) \
|
||||
_(NewSingletonCallObject) \
|
||||
|
@ -175,13 +175,6 @@ LIRGenerator::visitNewObject(MNewObject *ins)
|
||||
return define(lir, ins) && assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitNewTypedObject(MNewTypedObject *ins)
|
||||
{
|
||||
LNewTypedObject *lir = new(alloc()) LNewTypedObject(temp());
|
||||
return define(lir, ins) && assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitNewDeclEnvObject(MNewDeclEnvObject *ins)
|
||||
{
|
||||
|
@ -73,7 +73,6 @@ class LIRGenerator : public LIRGeneratorSpecific
|
||||
bool visitNewArray(MNewArray *ins);
|
||||
bool visitNewArrayCopyOnWrite(MNewArrayCopyOnWrite *ins);
|
||||
bool visitNewObject(MNewObject *ins);
|
||||
bool visitNewTypedObject(MNewTypedObject *ins);
|
||||
bool visitNewDeclEnvObject(MNewDeclEnvObject *ins);
|
||||
bool visitNewCallObject(MNewCallObject *ins);
|
||||
bool visitNewRunOnceCallObject(MNewRunOnceCallObject *ins);
|
||||
|
@ -280,18 +280,6 @@ IonBuilder::inlineNativeGetter(CallInfo &callInfo, JSFunction *target)
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
|
||||
IonBuilder::InliningStatus
|
||||
IonBuilder::inlineNonFunctionCall(CallInfo &callInfo, JSObject *target)
|
||||
{
|
||||
// Inline a call to a non-function object, invoking the object's call or
|
||||
// construct hook.
|
||||
|
||||
if (callInfo.constructing() && target->constructHook() == TypedObject::constructSized)
|
||||
return inlineConstructTypedObject(callInfo, &target->as<SizedTypeDescr>());
|
||||
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
|
||||
types::TemporaryTypeSet *
|
||||
IonBuilder::getInlineReturnTypeSet()
|
||||
{
|
||||
@ -2518,33 +2506,5 @@ IonBuilder::inlineIsConstructing(CallInfo &callInfo)
|
||||
return InliningStatus_Inlined;
|
||||
}
|
||||
|
||||
IonBuilder::InliningStatus
|
||||
IonBuilder::inlineConstructTypedObject(CallInfo &callInfo, SizedTypeDescr *descr)
|
||||
{
|
||||
// Only inline default constructors for now.
|
||||
if (callInfo.argc() != 0)
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
if (size_t(descr->size()) > InlineTypedObject::MaximumSize)
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
JSObject *obj = inspector->getTemplateObjectForClassHook(pc, descr->getClass());
|
||||
if (!obj || !obj->is<InlineTypedObject>())
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
InlineTypedObject *templateObject = &obj->as<InlineTypedObject>();
|
||||
if (&templateObject->typeDescr() != descr)
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
callInfo.setImplicitlyUsedUnchecked();
|
||||
|
||||
MNewTypedObject *ins = MNewTypedObject::New(alloc(), constraints(), templateObject,
|
||||
templateObject->type()->initialHeap(constraints()));
|
||||
current->add(ins);
|
||||
current->push(ins);
|
||||
|
||||
return InliningStatus_Inlined;
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
@ -2736,45 +2736,6 @@ class MNewPar : public MUnaryInstruction
|
||||
}
|
||||
};
|
||||
|
||||
class MNewTypedObject : public MNullaryInstruction
|
||||
{
|
||||
AlwaysTenured<InlineTypedObject *> templateObject_;
|
||||
gc::InitialHeap initialHeap_;
|
||||
|
||||
MNewTypedObject(types::CompilerConstraintList *constraints,
|
||||
InlineTypedObject *templateObject,
|
||||
gc::InitialHeap initialHeap)
|
||||
: templateObject_(templateObject),
|
||||
initialHeap_(initialHeap)
|
||||
{
|
||||
setResultType(MIRType_Object);
|
||||
setResultTypeSet(MakeSingletonTypeSet(constraints, templateObject));
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(NewTypedObject)
|
||||
|
||||
static MNewTypedObject *New(TempAllocator &alloc,
|
||||
types::CompilerConstraintList *constraints,
|
||||
InlineTypedObject *templateObject,
|
||||
gc::InitialHeap initialHeap)
|
||||
{
|
||||
return new(alloc) MNewTypedObject(constraints, templateObject, initialHeap);
|
||||
}
|
||||
|
||||
InlineTypedObject *templateObject() const {
|
||||
return templateObject_;
|
||||
}
|
||||
|
||||
gc::InitialHeap initialHeap() const {
|
||||
return initialHeap_;
|
||||
}
|
||||
|
||||
virtual AliasSet getAliasSet() const {
|
||||
return AliasSet::None();
|
||||
}
|
||||
};
|
||||
|
||||
class MTypedObjectProto
|
||||
: public MUnaryInstruction,
|
||||
public SingleObjectPolicy::Data
|
||||
|
@ -110,7 +110,6 @@ namespace jit {
|
||||
_(NewArray) \
|
||||
_(NewArrayCopyOnWrite) \
|
||||
_(NewObject) \
|
||||
_(NewTypedObject) \
|
||||
_(NewDeclEnvObject) \
|
||||
_(NewCallObject) \
|
||||
_(NewRunOnceCallObject) \
|
||||
|
@ -202,7 +202,6 @@ class ParallelSafetyVisitor : public MDefinitionVisitor
|
||||
CUSTOM_OP(ToString)
|
||||
CUSTOM_OP(NewArray)
|
||||
UNSAFE_OP(NewArrayCopyOnWrite)
|
||||
UNSAFE_OP(NewTypedObject)
|
||||
CUSTOM_OP(NewObject)
|
||||
CUSTOM_OP(NewCallObject)
|
||||
CUSTOM_OP(NewRunOnceCallObject)
|
||||
|
@ -17,7 +17,6 @@ namespace js {
|
||||
class DeclEnvObject;
|
||||
class ForkJoinContext;
|
||||
class StaticWithObject;
|
||||
class InlineTypedObject;
|
||||
|
||||
namespace jit {
|
||||
|
||||
@ -290,7 +289,6 @@ template <class> struct TypeToDataType { /* Unexpected return type for a VMFunct
|
||||
template <> struct TypeToDataType<bool> { static const DataType result = Type_Bool; };
|
||||
template <> struct TypeToDataType<JSObject *> { static const DataType result = Type_Object; };
|
||||
template <> struct TypeToDataType<NativeObject *> { static const DataType result = Type_Object; };
|
||||
template <> struct TypeToDataType<InlineTypedObject *> { static const DataType result = Type_Object; };
|
||||
template <> struct TypeToDataType<DeclEnvObject *> { static const DataType result = Type_Object; };
|
||||
template <> struct TypeToDataType<ArrayObject *> { static const DataType result = Type_Object; };
|
||||
template <> struct TypeToDataType<JSString *> { static const DataType result = Type_Object; };
|
||||
@ -300,7 +298,6 @@ template <> struct TypeToDataType<HandleString> { static const DataType result =
|
||||
template <> struct TypeToDataType<HandlePropertyName> { static const DataType result = Type_Handle; };
|
||||
template <> struct TypeToDataType<HandleFunction> { static const DataType result = Type_Handle; };
|
||||
template <> struct TypeToDataType<Handle<NativeObject *> > { static const DataType result = Type_Handle; };
|
||||
template <> struct TypeToDataType<Handle<InlineTypedObject *> > { static const DataType result = Type_Handle; };
|
||||
template <> struct TypeToDataType<Handle<ArrayObject *> > { static const DataType result = Type_Handle; };
|
||||
template <> struct TypeToDataType<Handle<StaticWithObject *> > { static const DataType result = Type_Handle; };
|
||||
template <> struct TypeToDataType<Handle<StaticBlockObject *> > { static const DataType result = Type_Handle; };
|
||||
@ -331,9 +328,6 @@ template <> struct TypeToArgProperties<HandleFunction> {
|
||||
template <> struct TypeToArgProperties<Handle<NativeObject *> > {
|
||||
static const uint32_t result = TypeToArgProperties<NativeObject *>::result | VMFunction::ByRef;
|
||||
};
|
||||
template <> struct TypeToArgProperties<Handle<InlineTypedObject *> > {
|
||||
static const uint32_t result = TypeToArgProperties<InlineTypedObject *>::result | VMFunction::ByRef;
|
||||
};
|
||||
template <> struct TypeToArgProperties<Handle<ArrayObject *> > {
|
||||
static const uint32_t result = TypeToArgProperties<ArrayObject *>::result | VMFunction::ByRef;
|
||||
};
|
||||
@ -402,9 +396,6 @@ template <> struct TypeToRootType<HandleScript> {
|
||||
template <> struct TypeToRootType<Handle<NativeObject *> > {
|
||||
static const uint32_t result = VMFunction::RootObject;
|
||||
};
|
||||
template <> struct TypeToRootType<Handle<InlineTypedObject *> > {
|
||||
static const uint32_t result = VMFunction::RootObject;
|
||||
};
|
||||
template <> struct TypeToRootType<Handle<ArrayObject *> > {
|
||||
static const uint32_t result = VMFunction::RootObject;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user