[INFER] More fixes for stock JM behavior, bug 647048.
This commit is contained in:
@@ -3070,9 +3070,9 @@ JS_NewCompartmentAndGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *pr
|
|||||||
AutoHoldCompartment hold(compartment);
|
AutoHoldCompartment hold(compartment);
|
||||||
|
|
||||||
JSCompartment *saved = cx->compartment;
|
JSCompartment *saved = cx->compartment;
|
||||||
cx->compartment = compartment;
|
cx->setCompartment(compartment);
|
||||||
JSObject *obj = JS_NewGlobalObject(cx, clasp);
|
JSObject *obj = JS_NewGlobalObject(cx, clasp);
|
||||||
cx->compartment = saved;
|
cx->setCompartment(saved);
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,6 +107,8 @@
|
|||||||
#include "jstracer.h"
|
#include "jstracer.h"
|
||||||
#include "jsvector.h"
|
#include "jsvector.h"
|
||||||
#include "jswrapper.h"
|
#include "jswrapper.h"
|
||||||
|
#include "methodjit/StubCalls.h"
|
||||||
|
#include "methodjit/StubCalls-inl.h"
|
||||||
|
|
||||||
#include "jsatominlines.h"
|
#include "jsatominlines.h"
|
||||||
#include "jscntxtinlines.h"
|
#include "jscntxtinlines.h"
|
||||||
@@ -667,8 +669,11 @@ array_length_setter(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value
|
|||||||
if (oldcap > newlen)
|
if (oldcap > newlen)
|
||||||
obj->shrinkDenseArrayElements(cx, newlen);
|
obj->shrinkDenseArrayElements(cx, newlen);
|
||||||
jsuint oldinit = obj->getDenseArrayInitializedLength();
|
jsuint oldinit = obj->getDenseArrayInitializedLength();
|
||||||
if (oldinit > newlen)
|
if (oldinit > newlen) {
|
||||||
obj->setDenseArrayInitializedLength(newlen);
|
obj->setDenseArrayInitializedLength(newlen);
|
||||||
|
if (!cx->typeInferenceEnabled())
|
||||||
|
obj->backfillDenseArrayHoles();
|
||||||
|
}
|
||||||
} else if (oldlen - newlen < (1 << 24)) {
|
} else if (oldlen - newlen < (1 << 24)) {
|
||||||
do {
|
do {
|
||||||
--oldlen;
|
--oldlen;
|
||||||
@@ -3499,10 +3504,11 @@ NewArray(JSContext *cx, jsuint length, JSObject *proto)
|
|||||||
if (allocateCapacity) {
|
if (allocateCapacity) {
|
||||||
if (!obj->ensureSlots(cx, length))
|
if (!obj->ensureSlots(cx, length))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!cx->typeInferenceEnabled())
|
|
||||||
obj->backfillDenseArrayHoles();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cx->typeInferenceEnabled())
|
||||||
|
obj->backfillDenseArrayHoles();
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3521,14 +3527,7 @@ NewDenseAllocatedArray(JSContext *cx, uint32 length, JSObject *proto)
|
|||||||
JSObject * JS_FASTCALL
|
JSObject * JS_FASTCALL
|
||||||
NewDenseAllocatedEmptyArray(JSContext *cx, uint length, JSObject *proto)
|
NewDenseAllocatedEmptyArray(JSContext *cx, uint length, JSObject *proto)
|
||||||
{
|
{
|
||||||
JSObject *obj = NewArray<true>(cx, length, proto);
|
return NewArray<true>(cx, length, proto);
|
||||||
if (!obj)
|
|
||||||
return NULL;
|
|
||||||
obj->setDenseArrayInitializedLength(length);
|
|
||||||
if (!obj->setDenseArrayNotPacked(cx))
|
|
||||||
return NULL;
|
|
||||||
ClearValueRange(obj->getSlots(), length, true);
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSObject * JS_FASTCALL
|
JSObject * JS_FASTCALL
|
||||||
@@ -3537,6 +3536,20 @@ NewDenseUnallocatedArray(JSContext *cx, uint32 length, JSObject *proto)
|
|||||||
return NewArray<false>(cx, length, proto);
|
return NewArray<false>(cx, length, proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef JS_METHODJIT
|
||||||
|
JSObject * JS_FASTCALL
|
||||||
|
mjit::stubs::NewDenseUnallocatedArray(VMFrame &f, uint32 length)
|
||||||
|
{
|
||||||
|
JSObject *proto = (JSObject *) f.scratch;
|
||||||
|
JSObject *obj = NewArray<false>(f.cx, length, proto);
|
||||||
|
if (!obj) {
|
||||||
|
js_ReportOutOfMemory(f.cx);
|
||||||
|
THROWV(NULL);
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
JSObject *
|
JSObject *
|
||||||
NewDenseCopiedArray(JSContext *cx, uintN length, Value *vp, JSObject *proto)
|
NewDenseCopiedArray(JSContext *cx, uintN length, Value *vp, JSObject *proto)
|
||||||
{
|
{
|
||||||
@@ -3546,11 +3559,15 @@ NewDenseCopiedArray(JSContext *cx, uintN length, Value *vp, JSObject *proto)
|
|||||||
|
|
||||||
JS_ASSERT(obj->getDenseArrayCapacity() >= length);
|
JS_ASSERT(obj->getDenseArrayCapacity() >= length);
|
||||||
|
|
||||||
if (vp) {
|
if (cx->typeInferenceEnabled()) {
|
||||||
|
if (vp) {
|
||||||
|
memcpy(obj->getDenseArrayElements(), vp, length * sizeof(Value));
|
||||||
|
obj->setDenseArrayInitializedLength(length);
|
||||||
|
} else {
|
||||||
|
obj->setDenseArrayInitializedLength(0);
|
||||||
|
}
|
||||||
|
} else if (vp) {
|
||||||
memcpy(obj->getDenseArrayElements(), vp, length * sizeof(Value));
|
memcpy(obj->getDenseArrayElements(), vp, length * sizeof(Value));
|
||||||
obj->setDenseArrayInitializedLength(length);
|
|
||||||
} else {
|
|
||||||
obj->setDenseArrayInitializedLength(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
|
|||||||
@@ -89,9 +89,16 @@ inline JSObject::EnsureDenseResult
|
|||||||
JSObject::ensureDenseArrayElements(JSContext *cx, uintN index, uintN extra)
|
JSObject::ensureDenseArrayElements(JSContext *cx, uintN index, uintN extra)
|
||||||
{
|
{
|
||||||
JS_ASSERT(isDenseArray());
|
JS_ASSERT(isDenseArray());
|
||||||
|
|
||||||
uintN currentCapacity = numSlots();
|
uintN currentCapacity = numSlots();
|
||||||
uintN initLength = getDenseArrayInitializedLength();
|
uintN initLength = getDenseArrayInitializedLength();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't take excessive slow paths when inference is disabled, due to
|
||||||
|
* uninitialized slots between initializedLength and capacity.
|
||||||
|
*/
|
||||||
|
JS_ASSERT_IF(!cx->typeInferenceEnabled(), currentCapacity == initLength);
|
||||||
|
|
||||||
uintN requiredCapacity;
|
uintN requiredCapacity;
|
||||||
if (extra == 1) {
|
if (extra == 1) {
|
||||||
/* Optimize for the common case. */
|
/* Optimize for the common case. */
|
||||||
|
|||||||
@@ -1958,6 +1958,7 @@ JSContext::resetCompartment()
|
|||||||
}
|
}
|
||||||
|
|
||||||
compartment = scopeobj->compartment();
|
compartment = scopeobj->compartment();
|
||||||
|
inferenceEnabled = compartment->types.inferenceEnabled;
|
||||||
|
|
||||||
if (isExceptionPending())
|
if (isExceptionPending())
|
||||||
wrapPendingException();
|
wrapPendingException();
|
||||||
|
|||||||
@@ -1648,6 +1648,8 @@ struct JSContext
|
|||||||
/* GC heap compartment. */
|
/* GC heap compartment. */
|
||||||
JSCompartment *compartment;
|
JSCompartment *compartment;
|
||||||
|
|
||||||
|
inline void setCompartment(JSCompartment *compartment);
|
||||||
|
|
||||||
/* Currently executing frame and regs, set by stack operations. */
|
/* Currently executing frame and regs, set by stack operations. */
|
||||||
JS_REQUIRES_STACK
|
JS_REQUIRES_STACK
|
||||||
JSFrameRegs *regs;
|
JSFrameRegs *regs;
|
||||||
@@ -1939,6 +1941,8 @@ struct JSContext
|
|||||||
bool profilingEnabled;
|
bool profilingEnabled;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool inferenceEnabled;
|
||||||
|
|
||||||
/* Caller must be holding runtime->gcLock. */
|
/* Caller must be holding runtime->gcLock. */
|
||||||
void updateJITEnabled();
|
void updateJITEnabled();
|
||||||
|
|
||||||
|
|||||||
@@ -572,6 +572,13 @@ GetMathCache(JSContext *cx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
JSContext::setCompartment(JSCompartment *compartment)
|
||||||
|
{
|
||||||
|
this->compartment = compartment;
|
||||||
|
this->inferenceEnabled = compartment ? compartment->types.inferenceEnabled : false;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
# define EVAL_CACHE_METER(x) (cx->compartment->evalCacheMeter.x++)
|
# define EVAL_CACHE_METER(x) (cx->compartment->evalCacheMeter.x++)
|
||||||
#else
|
#else
|
||||||
@@ -597,7 +604,7 @@ class PreserveCompartment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
~PreserveCompartment() {
|
~PreserveCompartment() {
|
||||||
cx->compartment = oldCompartment;
|
cx->setCompartment(oldCompartment);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -608,14 +615,14 @@ class SwitchToCompartment : public PreserveCompartment {
|
|||||||
: PreserveCompartment(cx)
|
: PreserveCompartment(cx)
|
||||||
{
|
{
|
||||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||||
cx->compartment = newCompartment;
|
cx->setCompartment(newCompartment);
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitchToCompartment(JSContext *cx, JSObject *target JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
SwitchToCompartment(JSContext *cx, JSObject *target JS_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||||
: PreserveCompartment(cx)
|
: PreserveCompartment(cx)
|
||||||
{
|
{
|
||||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||||
cx->compartment = target->getCompartment();
|
cx->setCompartment(target->getCompartment());
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
JS_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||||
|
|||||||
@@ -402,12 +402,12 @@ JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|||||||
#ifdef JS_METHODJIT
|
#ifdef JS_METHODJIT
|
||||||
if (script->hasJITCode()) {
|
if (script->hasJITCode()) {
|
||||||
JSCompartment *oldCompartment = cx->compartment;
|
JSCompartment *oldCompartment = cx->compartment;
|
||||||
cx->compartment = script->compartment;
|
cx->setCompartment(script->compartment);
|
||||||
|
|
||||||
mjit::Recompiler recompiler(cx, script);
|
mjit::Recompiler recompiler(cx, script);
|
||||||
recompiler.recompile();
|
recompiler.recompile();
|
||||||
|
|
||||||
cx->compartment = oldCompartment;
|
cx->setCompartment(oldCompartment);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ UseNewType(JSContext *cx, JSScript *script, jsbytecode *pc);
|
|||||||
inline bool
|
inline bool
|
||||||
JSContext::typeInferenceEnabled()
|
JSContext::typeInferenceEnabled()
|
||||||
{
|
{
|
||||||
return compartment->types.inferenceEnabled;
|
return inferenceEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline js::types::TypeObject *
|
inline js::types::TypeObject *
|
||||||
|
|||||||
@@ -389,13 +389,13 @@ AutoCompartment::enter()
|
|||||||
if (origin != destination) {
|
if (origin != destination) {
|
||||||
LeaveTrace(context);
|
LeaveTrace(context);
|
||||||
|
|
||||||
context->compartment = destination;
|
context->setCompartment(destination);
|
||||||
JSObject *scopeChain = target->getGlobal();
|
JSObject *scopeChain = target->getGlobal();
|
||||||
JS_ASSERT(scopeChain->isNative());
|
JS_ASSERT(scopeChain->isNative());
|
||||||
|
|
||||||
frame.construct();
|
frame.construct();
|
||||||
if (!context->stack().pushDummyFrame(context, *scopeChain, &frame.ref())) {
|
if (!context->stack().pushDummyFrame(context, *scopeChain, &frame.ref())) {
|
||||||
context->compartment = origin;
|
context->setCompartment(origin);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1916,11 +1916,15 @@ mjit::Compiler::generateMethod()
|
|||||||
END_CASE(JSOP_SETELEM);
|
END_CASE(JSOP_SETELEM);
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_CALLNAME)
|
BEGIN_CASE(JSOP_CALLNAME)
|
||||||
|
{
|
||||||
|
uint32 index = fullAtomIndex(PC);
|
||||||
prepareStubCall(Uses(0));
|
prepareStubCall(Uses(0));
|
||||||
masm.move(Imm32(fullAtomIndex(PC)), Registers::ArgReg1);
|
masm.move(Imm32(index), Registers::ArgReg1);
|
||||||
INLINE_STUBCALL(stubs::CallName);
|
INLINE_STUBCALL(stubs::CallName);
|
||||||
pushSyncedEntry(0);
|
pushSyncedEntry(0);
|
||||||
pushSyncedEntry(1);
|
pushSyncedEntry(1);
|
||||||
|
frame.extra(frame.peek(-2)).name = script->getAtom(index);
|
||||||
|
}
|
||||||
END_CASE(JSOP_CALLNAME)
|
END_CASE(JSOP_CALLNAME)
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_EVAL)
|
BEGIN_CASE(JSOP_EVAL)
|
||||||
@@ -1959,7 +1963,11 @@ mjit::Compiler::generateMethod()
|
|||||||
END_CASE(JSOP_CALL)
|
END_CASE(JSOP_CALL)
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_NAME)
|
BEGIN_CASE(JSOP_NAME)
|
||||||
jsop_name(script->getAtom(fullAtomIndex(PC)), knownPushedType(0));
|
{
|
||||||
|
JSAtom *atom = script->getAtom(fullAtomIndex(PC));
|
||||||
|
jsop_name(atom, knownPushedType(0));
|
||||||
|
frame.extra(frame.peek(-1)).name = atom;
|
||||||
|
}
|
||||||
END_CASE(JSOP_NAME)
|
END_CASE(JSOP_NAME)
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_DOUBLE)
|
BEGIN_CASE(JSOP_DOUBLE)
|
||||||
@@ -2480,9 +2488,13 @@ mjit::Compiler::generateMethod()
|
|||||||
|
|
||||||
BEGIN_CASE(JSOP_GETGNAME)
|
BEGIN_CASE(JSOP_GETGNAME)
|
||||||
BEGIN_CASE(JSOP_CALLGNAME)
|
BEGIN_CASE(JSOP_CALLGNAME)
|
||||||
jsop_getgname(fullAtomIndex(PC), knownPushedType(0));
|
{
|
||||||
|
uint32 index = fullAtomIndex(PC);
|
||||||
|
jsop_getgname(index, knownPushedType(0));
|
||||||
|
frame.extra(frame.peek(-1)).name = script->getAtom(index);
|
||||||
if (op == JSOP_CALLGNAME)
|
if (op == JSOP_CALLGNAME)
|
||||||
jsop_callgname_epilogue();
|
jsop_callgname_epilogue();
|
||||||
|
}
|
||||||
END_CASE(JSOP_GETGNAME)
|
END_CASE(JSOP_GETGNAME)
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_SETGNAME)
|
BEGIN_CASE(JSOP_SETGNAME)
|
||||||
@@ -2629,8 +2641,11 @@ mjit::Compiler::generateMethod()
|
|||||||
unsigned nuses = analyze::GetUseCount(script, oldPC - script->code);
|
unsigned nuses = analyze::GetUseCount(script, oldPC - script->code);
|
||||||
unsigned ndefs = analyze::GetDefCount(script, oldPC - script->code);
|
unsigned ndefs = analyze::GetDefCount(script, oldPC - script->code);
|
||||||
for (unsigned i = 0; i < ndefs; i++) {
|
for (unsigned i = 0; i < ndefs; i++) {
|
||||||
frame.learnTypeSet(opinfo->stackDepth - nuses + i,
|
FrameEntry *fe = frame.getStack(opinfo->stackDepth - nuses + i);
|
||||||
script->types->pushed(oldPC - script->code, i));
|
if (fe) {
|
||||||
|
/* fe may be NULL for conditionally pushed entries, e.g. JSOP_AND */
|
||||||
|
frame.extra(fe).types = script->types->pushed(oldPC - script->code, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3246,6 +3261,12 @@ mjit::Compiler::inlineCallHelper(uint32 callImmArgc, bool callingNew)
|
|||||||
if (callingNew)
|
if (callingNew)
|
||||||
frame.discardFe(origThis);
|
frame.discardFe(origThis);
|
||||||
|
|
||||||
|
if (!cx->typeInferenceEnabled()) {
|
||||||
|
CompileStatus status = callArrayBuiltin(callImmArgc, callingNew);
|
||||||
|
if (status != Compile_InlineAbort)
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* From the presence of JSOP_FUN{CALL,APPLY}, we speculate that we are
|
* From the presence of JSOP_FUN{CALL,APPLY}, we speculate that we are
|
||||||
* going to call js_fun_{call,apply}. Normally, this call would go through
|
* going to call js_fun_{call,apply}. Normally, this call would go through
|
||||||
@@ -3378,10 +3399,10 @@ mjit::Compiler::inlineCallHelper(uint32 callImmArgc, bool callingNew)
|
|||||||
js_ReportOutOfMemory(cx);
|
js_ReportOutOfMemory(cx);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
types::TypeSet *types = frame.getTypeSet(frame.peek(-(argc + 1)));
|
types::TypeSet *types = frame.extra(frame.peek(-(argc + 1))).types;
|
||||||
types::TypeSet::Clone(cx, types, &callIC.argTypes[0]);
|
types::TypeSet::Clone(cx, types, &callIC.argTypes[0]);
|
||||||
for (unsigned i = 0; i < argc; i++) {
|
for (unsigned i = 0; i < argc; i++) {
|
||||||
types::TypeSet *types = frame.getTypeSet(frame.peek(-(argc - i)));
|
types::TypeSet *types = frame.extra(frame.peek(-(argc - i))).types;
|
||||||
types::TypeSet::Clone(cx, types, &callIC.argTypes[i + 1]);
|
types::TypeSet::Clone(cx, types, &callIC.argTypes[i + 1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3587,6 +3608,91 @@ mjit::Compiler::inlineCallHelper(uint32 callImmArgc, bool callingNew)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompileStatus
|
||||||
|
mjit::Compiler::callArrayBuiltin(uint32 argc, bool callingNew)
|
||||||
|
{
|
||||||
|
if (applyTricks == LazyArgsObj)
|
||||||
|
return Compile_InlineAbort;
|
||||||
|
|
||||||
|
FrameEntry *origCallee = frame.peek(-(argc + 2));
|
||||||
|
if (origCallee->isNotType(JSVAL_TYPE_OBJECT))
|
||||||
|
return Compile_InlineAbort;
|
||||||
|
|
||||||
|
if (frame.extra(origCallee).name != cx->runtime->atomState.classAtoms[JSProto_Array])
|
||||||
|
return Compile_InlineAbort;
|
||||||
|
|
||||||
|
JSObject *arrayObj;
|
||||||
|
if (!js_GetClassObject(cx, globalObj, JSProto_Array, &arrayObj))
|
||||||
|
return Compile_Error;
|
||||||
|
|
||||||
|
JSObject *arrayProto;
|
||||||
|
if (!js_GetClassPrototype(cx, globalObj, JSProto_Array, &arrayProto))
|
||||||
|
return Compile_Error;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
return Compile_InlineAbort;
|
||||||
|
FrameEntry *origArg = (argc == 1) ? frame.peek(-1) : NULL;
|
||||||
|
if (origArg) {
|
||||||
|
if (origArg->isNotType(JSVAL_TYPE_INT32))
|
||||||
|
return Compile_InlineAbort;
|
||||||
|
if (origArg->isConstant() && origArg->getValue().toInt32() < 0)
|
||||||
|
return Compile_InlineAbort;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!origCallee->isTypeKnown()) {
|
||||||
|
Jump notObject = frame.testObject(Assembler::NotEqual, origCallee);
|
||||||
|
stubcc.linkExit(notObject, Uses(argc + 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterID reg = frame.tempRegForData(origCallee);
|
||||||
|
Jump notArray = masm.branchPtr(Assembler::NotEqual, reg, ImmPtr(arrayObj));
|
||||||
|
stubcc.linkExit(notArray, Uses(argc + 2));
|
||||||
|
|
||||||
|
int32 knownSize = 0;
|
||||||
|
MaybeRegisterID sizeReg;
|
||||||
|
if (origArg) {
|
||||||
|
if (origArg->isConstant()) {
|
||||||
|
knownSize = origArg->getValue().toInt32();
|
||||||
|
} else {
|
||||||
|
if (!origArg->isTypeKnown()) {
|
||||||
|
Jump notInt = frame.testInt32(Assembler::NotEqual, origArg);
|
||||||
|
stubcc.linkExit(notInt, Uses(argc + 2));
|
||||||
|
}
|
||||||
|
sizeReg = frame.tempRegForData(origArg);
|
||||||
|
Jump belowZero = masm.branch32(Assembler::LessThan, sizeReg.reg(), Imm32(0));
|
||||||
|
stubcc.linkExit(belowZero, Uses(argc + 2));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
knownSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
stubcc.leave();
|
||||||
|
stubcc.masm.move(Imm32(argc), Registers::ArgReg1);
|
||||||
|
OOL_STUBCALL(callingNew ? stubs::SlowNew : stubs::SlowCall);
|
||||||
|
|
||||||
|
{
|
||||||
|
PinRegAcrossSyncAndKill p1(frame, sizeReg);
|
||||||
|
frame.popn(argc + 2);
|
||||||
|
frame.syncAndKill(Uses(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareStubCall(Uses(0));
|
||||||
|
masm.storePtr(ImmPtr(arrayProto), FrameAddress(offsetof(VMFrame, scratch)));
|
||||||
|
if (sizeReg.isSet())
|
||||||
|
masm.move(sizeReg.reg(), Registers::ArgReg1);
|
||||||
|
else
|
||||||
|
masm.move(Imm32(knownSize), Registers::ArgReg1);
|
||||||
|
INLINE_STUBCALL(stubs::NewDenseUnallocatedArray);
|
||||||
|
|
||||||
|
frame.takeReg(Registers::ReturnReg);
|
||||||
|
frame.pushTypedPayload(JSVAL_TYPE_OBJECT, Registers::ReturnReg);
|
||||||
|
frame.forgetType(frame.peek(-1));
|
||||||
|
|
||||||
|
stubcc.rejoin(Changes(1));
|
||||||
|
|
||||||
|
return Compile_Okay;
|
||||||
|
}
|
||||||
|
|
||||||
/* Maximum number of calls we will inline at the same site. */
|
/* Maximum number of calls we will inline at the same site. */
|
||||||
static const uint32 INLINE_SITE_LIMIT = 5;
|
static const uint32 INLINE_SITE_LIMIT = 5;
|
||||||
|
|
||||||
@@ -3608,7 +3714,7 @@ mjit::Compiler::inlineScriptedFunction(uint32 argc, bool callingNew)
|
|||||||
FrameEntry *origCallee = frame.peek(-(argc + 2));
|
FrameEntry *origCallee = frame.peek(-(argc + 2));
|
||||||
FrameEntry *origThis = frame.peek(-(argc + 1));
|
FrameEntry *origThis = frame.peek(-(argc + 1));
|
||||||
|
|
||||||
types::TypeSet *types = frame.getTypeSet(origCallee);
|
types::TypeSet *types = frame.extra(origCallee).types;
|
||||||
if (!types || types->getKnownTypeTag(cx) != JSVAL_TYPE_OBJECT)
|
if (!types || types->getKnownTypeTag(cx) != JSVAL_TYPE_OBJECT)
|
||||||
return Compile_InlineAbort;
|
return Compile_InlineAbort;
|
||||||
|
|
||||||
@@ -4497,7 +4603,7 @@ mjit::Compiler::testSingletonPropertyTypes(FrameEntry *top, jsid id, bool *testO
|
|||||||
{
|
{
|
||||||
*testObject = false;
|
*testObject = false;
|
||||||
|
|
||||||
types::TypeSet *types = frame.getTypeSet(top);
|
types::TypeSet *types = frame.extra(top).types;
|
||||||
if (!types)
|
if (!types)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -4619,7 +4725,7 @@ mjit::Compiler::jsop_setprop(JSAtom *atom, bool usePropCache)
|
|||||||
pic.atom = atom;
|
pic.atom = atom;
|
||||||
|
|
||||||
if (monitored(PC)) {
|
if (monitored(PC)) {
|
||||||
types::TypeSet *types = frame.getTypeSet(rhs);
|
types::TypeSet *types = frame.extra(rhs).types;
|
||||||
pic.typeMonitored = true;
|
pic.typeMonitored = true;
|
||||||
pic.rhsTypes = (types::ClonedTypeSet *) ::js_calloc(sizeof(types::ClonedTypeSet));
|
pic.rhsTypes = (types::ClonedTypeSet *) ::js_calloc(sizeof(types::ClonedTypeSet));
|
||||||
if (!pic.rhsTypes) {
|
if (!pic.rhsTypes) {
|
||||||
@@ -6048,7 +6154,10 @@ mjit::Compiler::jsop_newinit()
|
|||||||
INLINE_STUBCALL(stubs::NewInitObject);
|
INLINE_STUBCALL(stubs::NewInitObject);
|
||||||
}
|
}
|
||||||
frame.takeReg(Registers::ReturnReg);
|
frame.takeReg(Registers::ReturnReg);
|
||||||
frame.pushInitializerObject(Registers::ReturnReg, *PC == JSOP_NEWARRAY, baseobj);
|
frame.pushTypedPayload(JSVAL_TYPE_OBJECT, Registers::ReturnReg);
|
||||||
|
|
||||||
|
frame.extra(frame.peek(-1)).initArray = (*PC == JSOP_NEWARRAY);
|
||||||
|
frame.extra(frame.peek(-1)).initObject = baseobj;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -6211,6 +6320,10 @@ mjit::Compiler::jumpAndTrace(Jump j, jsbytecode *target, Jump *slow, bool *tramp
|
|||||||
|
|
||||||
# if JS_MONOIC
|
# if JS_MONOIC
|
||||||
ic.addrLabel = stubcc.masm.moveWithPatch(ImmPtr(NULL), Registers::ArgReg1);
|
ic.addrLabel = stubcc.masm.moveWithPatch(ImmPtr(NULL), Registers::ArgReg1);
|
||||||
|
|
||||||
|
Jump nonzero = stubcc.masm.branchSub32(Assembler::NonZero, Imm32(1),
|
||||||
|
Address(Registers::ArgReg1,
|
||||||
|
offsetof(TraceICInfo, loopCounter)));
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/* Save and restore compiler-tracked PC, so cx->regs is right in InvokeTracer. */
|
/* Save and restore compiler-tracked PC, so cx->regs is right in InvokeTracer. */
|
||||||
@@ -6225,13 +6338,14 @@ mjit::Compiler::jumpAndTrace(Jump j, jsbytecode *target, Jump *slow, bool *tramp
|
|||||||
|
|
||||||
Jump no = stubcc.masm.branchTestPtr(Assembler::Zero, Registers::ReturnReg,
|
Jump no = stubcc.masm.branchTestPtr(Assembler::Zero, Registers::ReturnReg,
|
||||||
Registers::ReturnReg);
|
Registers::ReturnReg);
|
||||||
|
if (!cx->typeInferenceEnabled())
|
||||||
|
stubcc.masm.loadPtr(FrameAddress(offsetof(VMFrame, regs.fp)), JSFrameReg);
|
||||||
stubcc.masm.jump(Registers::ReturnReg);
|
stubcc.masm.jump(Registers::ReturnReg);
|
||||||
no.linkTo(stubcc.masm.label(), &stubcc.masm);
|
no.linkTo(stubcc.masm.label(), &stubcc.masm);
|
||||||
|
|
||||||
if (!cx->typeInferenceEnabled())
|
|
||||||
stubcc.masm.loadPtr(FrameAddress(offsetof(VMFrame, regs.fp)), JSFrameReg);
|
|
||||||
|
|
||||||
#ifdef JS_MONOIC
|
#ifdef JS_MONOIC
|
||||||
|
nonzero.linkTo(stubcc.masm.label(), &stubcc.masm);
|
||||||
|
|
||||||
ic.jumpTarget = target;
|
ic.jumpTarget = target;
|
||||||
ic.fastTrampoline = !consistent;
|
ic.fastTrampoline = !consistent;
|
||||||
ic.trampolineStart = stubcc.masm.label();
|
ic.trampolineStart = stubcc.masm.label();
|
||||||
|
|||||||
@@ -680,6 +680,7 @@ class Compiler : public BaseCompiler
|
|||||||
|
|
||||||
/* Fast builtins. */
|
/* Fast builtins. */
|
||||||
JSObject *pushedSingleton(unsigned pushed);
|
JSObject *pushedSingleton(unsigned pushed);
|
||||||
|
CompileStatus callArrayBuiltin(uint32 argc, bool callingNew);
|
||||||
CompileStatus inlineNativeFunction(uint32 argc, bool callingNew);
|
CompileStatus inlineNativeFunction(uint32 argc, bool callingNew);
|
||||||
CompileStatus inlineScriptedFunction(uint32 argc, bool callingNew);
|
CompileStatus inlineScriptedFunction(uint32 argc, bool callingNew);
|
||||||
CompileStatus compileMathAbsInt(FrameEntry *arg);
|
CompileStatus compileMathAbsInt(FrameEntry *arg);
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ mjit::Compiler::inlineNativeFunction(uint32 argc, bool callingNew)
|
|||||||
{
|
{
|
||||||
JS_ASSERT(!callingNew);
|
JS_ASSERT(!callingNew);
|
||||||
|
|
||||||
if (cx->typeInferenceEnabled())
|
if (!cx->typeInferenceEnabled())
|
||||||
return Compile_InlineAbort;
|
return Compile_InlineAbort;
|
||||||
|
|
||||||
if (applyTricks == LazyArgsObj)
|
if (applyTricks == LazyArgsObj)
|
||||||
|
|||||||
@@ -483,8 +483,8 @@ mjit::Compiler::jsop_equality(JSOp op, BoolStub stub, jsbytecode *target, JSOp f
|
|||||||
* special equality operator on either object, if that passes then
|
* special equality operator on either object, if that passes then
|
||||||
* this is a pointer comparison.
|
* this is a pointer comparison.
|
||||||
*/
|
*/
|
||||||
types::TypeSet *lhsTypes = frame.getTypeSet(lhs);
|
types::TypeSet *lhsTypes = frame.extra(lhs).types;
|
||||||
types::TypeSet *rhsTypes = frame.getTypeSet(rhs);
|
types::TypeSet *rhsTypes = frame.extra(rhs).types;
|
||||||
types::ObjectKind lhsKind =
|
types::ObjectKind lhsKind =
|
||||||
lhsTypes ? lhsTypes->getKnownObjectKind(cx) : types::OBJECT_UNKNOWN;
|
lhsTypes ? lhsTypes->getKnownObjectKind(cx) : types::OBJECT_UNKNOWN;
|
||||||
types::ObjectKind rhsKind =
|
types::ObjectKind rhsKind =
|
||||||
@@ -1189,7 +1189,7 @@ mjit::Compiler::jsop_setelem(bool popGuaranteed)
|
|||||||
frame.forgetConstantData(obj);
|
frame.forgetConstantData(obj);
|
||||||
|
|
||||||
if (cx->typeInferenceEnabled()) {
|
if (cx->typeInferenceEnabled()) {
|
||||||
types::TypeSet *types = frame.getTypeSet(obj);
|
types::TypeSet *types = frame.extra(obj).types;
|
||||||
types::ObjectKind kind = types
|
types::ObjectKind kind = types
|
||||||
? types->getKnownObjectKind(cx)
|
? types->getKnownObjectKind(cx)
|
||||||
: types::OBJECT_UNKNOWN;
|
: types::OBJECT_UNKNOWN;
|
||||||
@@ -1509,7 +1509,7 @@ mjit::Compiler::jsop_getelem(bool isCall)
|
|||||||
frame.forgetConstantData(obj);
|
frame.forgetConstantData(obj);
|
||||||
|
|
||||||
if (cx->typeInferenceEnabled()) {
|
if (cx->typeInferenceEnabled()) {
|
||||||
types::TypeSet *types = frame.getTypeSet(obj);
|
types::TypeSet *types = frame.extra(obj).types;
|
||||||
types::ObjectKind kind = types
|
types::ObjectKind kind = types
|
||||||
? types->getKnownObjectKind(cx)
|
? types->getKnownObjectKind(cx)
|
||||||
: types::OBJECT_UNKNOWN;
|
: types::OBJECT_UNKNOWN;
|
||||||
@@ -1950,7 +1950,7 @@ mjit::Compiler::jsop_initmethod()
|
|||||||
JSAtom *atom = script->getAtom(fullAtomIndex(PC));
|
JSAtom *atom = script->getAtom(fullAtomIndex(PC));
|
||||||
|
|
||||||
/* Initializers with INITMETHOD are not fast yet. */
|
/* Initializers with INITMETHOD are not fast yet. */
|
||||||
JS_ASSERT(!obj->initializerObject());
|
JS_ASSERT(!frame.extra(obj).initObject);
|
||||||
|
|
||||||
prepareStubCall(Uses(2));
|
prepareStubCall(Uses(2));
|
||||||
masm.move(ImmPtr(atom), Registers::ArgReg1);
|
masm.move(ImmPtr(atom), Registers::ArgReg1);
|
||||||
@@ -1964,7 +1964,7 @@ mjit::Compiler::jsop_initprop()
|
|||||||
FrameEntry *fe = frame.peek(-1);
|
FrameEntry *fe = frame.peek(-1);
|
||||||
JSAtom *atom = script->getAtom(fullAtomIndex(PC));
|
JSAtom *atom = script->getAtom(fullAtomIndex(PC));
|
||||||
|
|
||||||
JSObject *baseobj = obj->initializerObject();
|
JSObject *baseobj = frame.extra(obj).initObject;
|
||||||
|
|
||||||
if (!baseobj || monitored(PC)) {
|
if (!baseobj || monitored(PC)) {
|
||||||
prepareStubCall(Uses(2));
|
prepareStubCall(Uses(2));
|
||||||
@@ -2005,7 +2005,7 @@ mjit::Compiler::jsop_initelem()
|
|||||||
* cases, as well as those where INITELEM is used on an object initializer
|
* cases, as well as those where INITELEM is used on an object initializer
|
||||||
* or a non-fast array initializer.
|
* or a non-fast array initializer.
|
||||||
*/
|
*/
|
||||||
if (!id->isConstant() || !obj->initializerArray()) {
|
if (!id->isConstant() || !frame.extra(obj).initArray) {
|
||||||
JSOp next = JSOp(PC[JSOP_INITELEM_LENGTH]);
|
JSOp next = JSOp(PC[JSOP_INITELEM_LENGTH]);
|
||||||
|
|
||||||
prepareStubCall(Uses(3));
|
prepareStubCall(Uses(3));
|
||||||
|
|||||||
@@ -138,14 +138,6 @@ class FrameEntry
|
|||||||
bool isCopy() const { return !!copy; }
|
bool isCopy() const { return !!copy; }
|
||||||
bool isCopied() const { return copied; }
|
bool isCopied() const { return copied; }
|
||||||
|
|
||||||
inline bool initializerArray() {
|
|
||||||
return initArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline JSObject *initializerObject() {
|
|
||||||
return initObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setType(JSValueType type_) {
|
void setType(JSValueType type_) {
|
||||||
type.setConstant();
|
type.setConstant();
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ FrameState::pop()
|
|||||||
|
|
||||||
forgetAllRegs(fe);
|
forgetAllRegs(fe);
|
||||||
|
|
||||||
a->typeSets[fe - spBase] = NULL;
|
a->extraArray[fe - spBase].reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
@@ -238,7 +238,7 @@ FrameState::rawPush()
|
|||||||
if (!sp->isTracked())
|
if (!sp->isTracked())
|
||||||
addToTracker(sp);
|
addToTracker(sp);
|
||||||
|
|
||||||
a->typeSets[sp - spBase] = NULL;
|
a->extraArray[sp - spBase].reset();
|
||||||
|
|
||||||
return sp++;
|
return sp++;
|
||||||
}
|
}
|
||||||
@@ -403,16 +403,6 @@ FrameState::pushInt32(RegisterID payload)
|
|||||||
regstate(payload).associate(fe, RematInfo::DATA);
|
regstate(payload).associate(fe, RematInfo::DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
|
||||||
FrameState::pushInitializerObject(RegisterID payload, bool array, JSObject *baseobj)
|
|
||||||
{
|
|
||||||
pushTypedPayload(JSVAL_TYPE_OBJECT, payload);
|
|
||||||
|
|
||||||
FrameEntry *fe = peek(-1);
|
|
||||||
fe->initArray = array;
|
|
||||||
fe->initObject = baseobj;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
FrameState::pushUntypedPayload(JSValueType type, RegisterID payload)
|
FrameState::pushUntypedPayload(JSValueType type, RegisterID payload)
|
||||||
{
|
{
|
||||||
@@ -870,20 +860,6 @@ FrameState::forgetType(FrameEntry *fe)
|
|||||||
fe->type.setMemory();
|
fe->type.setMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline types::TypeSet *
|
|
||||||
FrameState::getTypeSet(FrameEntry *fe)
|
|
||||||
{
|
|
||||||
JS_ASSERT(fe >= spBase && fe < sp);
|
|
||||||
return a->typeSets[fe - spBase];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
FrameState::learnTypeSet(unsigned slot, types::TypeSet *types)
|
|
||||||
{
|
|
||||||
if (slot < unsigned(sp - spBase))
|
|
||||||
a->typeSets[slot] = types;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
FrameState::learnType(FrameEntry *fe, JSValueType type, bool unsync)
|
FrameState::learnType(FrameEntry *fe, JSValueType type, bool unsync)
|
||||||
{
|
{
|
||||||
@@ -1058,7 +1034,8 @@ FrameState::getOrTrack(uint32 index)
|
|||||||
inline FrameEntry *
|
inline FrameEntry *
|
||||||
FrameState::getStack(uint32 slot)
|
FrameState::getStack(uint32 slot)
|
||||||
{
|
{
|
||||||
JS_ASSERT(slot < uint32(sp - spBase));
|
if (slot >= uint32(sp - spBase))
|
||||||
|
return NULL;
|
||||||
return getOrTrack(uint32(&spBase[slot] - entries));
|
return getOrTrack(uint32(&spBase[slot] - entries));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ FrameState::pushActiveFrame(JSScript *script, uint32 argc,
|
|||||||
size_t totalBytes = sizeof(ActiveFrame) +
|
size_t totalBytes = sizeof(ActiveFrame) +
|
||||||
sizeof(FrameEntry) * nentries + // entries[]
|
sizeof(FrameEntry) * nentries + // entries[]
|
||||||
sizeof(FrameEntry *) * nentries + // tracker.entries
|
sizeof(FrameEntry *) * nentries + // tracker.entries
|
||||||
sizeof(types::TypeSet *) * script->nslots; // typeSets
|
sizeof(StackEntryExtra) * script->nslots; // extraArray
|
||||||
|
|
||||||
uint8 *cursor = (uint8 *)cx->calloc(totalBytes);
|
uint8 *cursor = (uint8 *)cx->calloc(totalBytes);
|
||||||
if (!cursor)
|
if (!cursor)
|
||||||
@@ -164,8 +164,8 @@ FrameState::pushActiveFrame(JSScript *script, uint32 argc,
|
|||||||
newa->tracker.entries = (FrameEntry **)cursor;
|
newa->tracker.entries = (FrameEntry **)cursor;
|
||||||
cursor += sizeof(FrameEntry *) * nentries;
|
cursor += sizeof(FrameEntry *) * nentries;
|
||||||
|
|
||||||
newa->typeSets = (types::TypeSet **)cursor;
|
newa->extraArray = (StackEntryExtra *)cursor;
|
||||||
cursor += sizeof(types::TypeSet *) * script->nslots;
|
cursor += sizeof(StackEntryExtra) * script->nslots;
|
||||||
|
|
||||||
JS_ASSERT(reinterpret_cast<uint8 *>(newa) + totalBytes == cursor);
|
JS_ASSERT(reinterpret_cast<uint8 *>(newa) + totalBytes == cursor);
|
||||||
|
|
||||||
@@ -1108,7 +1108,8 @@ FrameState::discardForJoin(jsbytecode *target, uint32 stackDepth)
|
|||||||
|
|
||||||
sp = spBase + stackDepth;
|
sp = spBase + stackDepth;
|
||||||
|
|
||||||
PodZero(a->typeSets, stackDepth);
|
for (unsigned i = 0; i < stackDepth; i++)
|
||||||
|
a->extraArray[i].reset();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2443,7 +2444,7 @@ FrameState::forgetEntry(FrameEntry *fe)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fe >= sp)
|
if (fe >= sp)
|
||||||
a->typeSets[fe - spBase] = NULL;
|
a->extraArray[fe - spBase].reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -326,12 +326,6 @@ class FrameState
|
|||||||
*/
|
*/
|
||||||
inline void pushInt32(RegisterID payload);
|
inline void pushInt32(RegisterID payload);
|
||||||
|
|
||||||
/*
|
|
||||||
* Pushes an initializer with specified payload, storing whether it is an array
|
|
||||||
* or object whose contents can be initialized in fast paths.
|
|
||||||
*/
|
|
||||||
inline void pushInitializerObject(RegisterID payload, bool array, JSObject *baseobj);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pops a value off the operation stack, freeing any of its resources.
|
* Pops a value off the operation stack, freeing any of its resources.
|
||||||
*/
|
*/
|
||||||
@@ -673,11 +667,18 @@ class FrameState
|
|||||||
*/
|
*/
|
||||||
void discardFe(FrameEntry *fe);
|
void discardFe(FrameEntry *fe);
|
||||||
|
|
||||||
/* Get a set with the possible types of a stack fe, or NULL. */
|
/* Compiler-owned metadata about stack entries, reset on push/pop/copy. */
|
||||||
inline types::TypeSet *getTypeSet(FrameEntry *fe);
|
struct StackEntryExtra {
|
||||||
|
bool initArray;
|
||||||
/* Mark a stack index as holding a particular type set. */
|
JSObject *initObject;
|
||||||
inline void learnTypeSet(unsigned slot, types::TypeSet *types);
|
types::TypeSet *types;
|
||||||
|
JSAtom *name;
|
||||||
|
void reset() { PodZero(this); }
|
||||||
|
};
|
||||||
|
StackEntryExtra& extra(FrameEntry *fe) {
|
||||||
|
JS_ASSERT(fe >= spBase && fe < sp);
|
||||||
|
return a->extraArray[fe - spBase];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper function. Tests if a slot's type is null. Condition must
|
* Helper function. Tests if a slot's type is null. Condition must
|
||||||
@@ -1031,8 +1032,8 @@ class FrameState
|
|||||||
/* Vector of tracked slot indexes. */
|
/* Vector of tracked slot indexes. */
|
||||||
Tracker tracker;
|
Tracker tracker;
|
||||||
|
|
||||||
/* Type sets for the stack contents. */
|
/* Compiler-owned metadata for the stack contents. */
|
||||||
types::TypeSet **typeSets;
|
StackEntryExtra *extraArray;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register ownership state. This can't be used alone; to find whether an
|
* Register ownership state. This can't be used alone; to find whether an
|
||||||
|
|||||||
@@ -191,6 +191,8 @@ InlineReturn(VMFrame &f)
|
|||||||
void JS_FASTCALL
|
void JS_FASTCALL
|
||||||
stubs::SlowCall(VMFrame &f, uint32 argc)
|
stubs::SlowCall(VMFrame &f, uint32 argc)
|
||||||
{
|
{
|
||||||
|
printf("CALL\n");
|
||||||
|
|
||||||
Value *vp = f.regs.sp - (argc + 2);
|
Value *vp = f.regs.sp - (argc + 2);
|
||||||
|
|
||||||
if (!Invoke(f.cx, InvokeArgsAlreadyOnTheStack(vp, argc), 0))
|
if (!Invoke(f.cx, InvokeArgsAlreadyOnTheStack(vp, argc), 0))
|
||||||
@@ -200,6 +202,8 @@ stubs::SlowCall(VMFrame &f, uint32 argc)
|
|||||||
void JS_FASTCALL
|
void JS_FASTCALL
|
||||||
stubs::SlowNew(VMFrame &f, uint32 argc)
|
stubs::SlowNew(VMFrame &f, uint32 argc)
|
||||||
{
|
{
|
||||||
|
printf("NEW\n");
|
||||||
|
|
||||||
JSContext *cx = f.cx;
|
JSContext *cx = f.cx;
|
||||||
Value *vp = f.regs.sp - (argc + 2);
|
Value *vp = f.regs.sp - (argc + 2);
|
||||||
|
|
||||||
|
|||||||
@@ -232,6 +232,9 @@ void JS_FASTCALL ConvertToTypedFloat(JSContext *cx, Value *vp);
|
|||||||
|
|
||||||
void JS_FASTCALL Exception(VMFrame &f);
|
void JS_FASTCALL Exception(VMFrame &f);
|
||||||
|
|
||||||
|
JSObject * JS_FASTCALL
|
||||||
|
NewDenseUnallocatedArray(VMFrame &f, uint32 length);
|
||||||
|
|
||||||
} /* namespace stubs */
|
} /* namespace stubs */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user