Backed out changeset 062226e8a2d2 (bug 1091015) for SM test failures.

This commit is contained in:
Ryan VanderMeulen 2014-11-03 14:12:32 -05:00
parent aaced0941c
commit 52c9f5e3b8
21 changed files with 102 additions and 543 deletions

View File

@ -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)
{

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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()
{

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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) {

View File

@ -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,

View File

@ -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

View File

@ -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);

View File

@ -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:

View File

@ -48,7 +48,6 @@
_(NewArrayCopyOnWrite) \
_(ArraySplice) \
_(NewObject) \
_(NewTypedObject) \
_(NewDeclEnvObject) \
_(NewCallObject) \
_(NewSingletonCallObject) \

View File

@ -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)
{

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -110,7 +110,6 @@ namespace jit {
_(NewArray) \
_(NewArrayCopyOnWrite) \
_(NewObject) \
_(NewTypedObject) \
_(NewDeclEnvObject) \
_(NewCallObject) \
_(NewRunOnceCallObject) \

View File

@ -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)

View File

@ -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;
};