mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backed out changeset 4ca9a6bd8f64 (bug 865059) for jsreftest crashes.
This commit is contained in:
parent
0dbb3c55f6
commit
c7f7e6de00
@ -4367,9 +4367,6 @@ EmitNormalFor(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
if (EmitJump(cx, bce, op, top - bce->offset()) < 0)
|
||||
return false;
|
||||
|
||||
if (!bce->tryNoteList.append(JSTRY_LOOP, bce->stackDepth, top, bce->offset()))
|
||||
return false;
|
||||
|
||||
/* Now fixup all breaks and continues. */
|
||||
return PopStatementBCE(cx, bce);
|
||||
}
|
||||
@ -4556,9 +4553,6 @@ EmitDo(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
if (beq < 0)
|
||||
return false;
|
||||
|
||||
if (!bce->tryNoteList.append(JSTRY_LOOP, bce->stackDepth, top, bce->offset()))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* Be careful: We must set noteIndex2 before noteIndex in case the noteIndex
|
||||
* note gets bigger.
|
||||
@ -4615,9 +4609,6 @@ EmitWhile(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn, ptrdiff_t top)
|
||||
if (beq < 0)
|
||||
return false;
|
||||
|
||||
if (!bce->tryNoteList.append(JSTRY_LOOP, bce->stackDepth, top, bce->offset()))
|
||||
return false;
|
||||
|
||||
if (!SetSrcNoteOffset(cx, bce, noteIndex, 0, beq - jmp))
|
||||
return false;
|
||||
|
||||
|
@ -10,20 +10,6 @@
|
||||
using namespace js;
|
||||
using namespace js::ion;
|
||||
|
||||
bool
|
||||
SetElemICInspector::sawOOBDenseWrite() const
|
||||
{
|
||||
if (!icEntry_)
|
||||
return false;
|
||||
|
||||
// Check for a SetElem_DenseAdd stub.
|
||||
for (ICStub *stub = icEntry_->firstStub(); stub; stub = stub->next()) {
|
||||
if (stub->isSetElem_DenseAdd())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
SetElemICInspector::sawOOBTypedArrayWrite() const
|
||||
{
|
||||
|
@ -39,7 +39,6 @@ class SetElemICInspector : public ICInspector
|
||||
: ICInspector(inspector, pc, icEntry)
|
||||
{ }
|
||||
|
||||
bool sawOOBDenseWrite() const;
|
||||
bool sawOOBTypedArrayWrite() const;
|
||||
};
|
||||
|
||||
|
@ -197,7 +197,7 @@ IonBuilder::canEnterInlinedFunction(JSFunction *target)
|
||||
{
|
||||
RootedScript targetScript(cx, target->nonLazyScript());
|
||||
|
||||
if (!targetScript->ensureRanAnalysis(cx))
|
||||
if (!targetScript->hasAnalysis())
|
||||
return false;
|
||||
|
||||
if (!targetScript->analysis()->ionInlineable())
|
||||
@ -313,7 +313,7 @@ IonBuilder::analyzeNewLoopTypes(MBasicBlock *entry, jsbytecode *start, jsbytecod
|
||||
MPhi *phi = entry->getSlot(slot)->toPhi();
|
||||
|
||||
if (js_CodeSpec[*last].format & JOF_TYPESET) {
|
||||
types::StackTypeSet *typeSet = types::TypeScript::BytecodeTypes(script(), last);
|
||||
types::StackTypeSet *typeSet = script()->analysis()->bytecodeTypes(last);
|
||||
if (!typeSet->empty()) {
|
||||
MIRType type = MIRTypeFromValueType(typeSet->getKnownTypeTag());
|
||||
phi->addBackedgeType(type, typeSet);
|
||||
@ -427,9 +427,6 @@ IonBuilder::pushLoop(CFGState::State initial, jsbytecode *stopAt, MBasicBlock *e
|
||||
bool
|
||||
IonBuilder::build()
|
||||
{
|
||||
if (!script()->ensureHasBytecodeTypeMap(cx))
|
||||
return false;
|
||||
|
||||
setCurrentAndSpecializePhis(newBlock(pc));
|
||||
if (!current)
|
||||
return false;
|
||||
@ -4554,7 +4551,7 @@ IonBuilder::jsop_funapplyarguments(uint32_t argc)
|
||||
if (!resumeAfter(apply))
|
||||
return false;
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
types::StackTypeSet *types = script()->analysis()->bytecodeTypes(pc);
|
||||
return pushTypeBarrier(apply, types, true);
|
||||
}
|
||||
|
||||
@ -4875,7 +4872,7 @@ IonBuilder::makeCall(HandleFunction target, CallInfo &callInfo, bool cloneAtCall
|
||||
if (!resumeAfter(call))
|
||||
return false;
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
types::StackTypeSet *types = script()->analysis()->bytecodeTypes(pc);
|
||||
|
||||
bool barrier = true;
|
||||
if (call->isDOMFunction()) {
|
||||
@ -4968,7 +4965,7 @@ IonBuilder::jsop_eval(uint32_t argc)
|
||||
current->add(ins);
|
||||
current->push(ins);
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
types::StackTypeSet *types = script()->analysis()->bytecodeTypes(pc);
|
||||
return resumeAfter(ins) && pushTypeBarrier(ins, types, true);
|
||||
}
|
||||
|
||||
@ -5021,7 +5018,7 @@ IonBuilder::jsop_newarray(uint32_t count)
|
||||
return false;
|
||||
|
||||
types::StackTypeSet::DoubleConversion conversion =
|
||||
types::TypeScript::BytecodeTypes(script(), pc)->convertDoubleElements(cx);
|
||||
script()->analysis()->bytecodeTypes(pc)->convertDoubleElements(cx);
|
||||
if (conversion == types::StackTypeSet::AlwaysConvertToDoubles)
|
||||
templateObject->setShouldConvertDoubleElements();
|
||||
|
||||
@ -5422,10 +5419,7 @@ IonBuilder::newPendingLoopHeader(MBasicBlock *predecessor, jsbytecode *pc, bool
|
||||
|
||||
bool haveValue = false;
|
||||
Value existingValue;
|
||||
if (info().fun() && i == info().thisSlot()) {
|
||||
haveValue = true;
|
||||
existingValue = fp.thisValue();
|
||||
} else {
|
||||
{
|
||||
uint32_t arg = i - info().firstArgSlot();
|
||||
uint32_t var = i - info().firstLocalSlot();
|
||||
if (arg < info().nargs()) {
|
||||
@ -5826,7 +5820,7 @@ IonBuilder::jsop_getgname(HandlePropertyName name)
|
||||
return jsop_getname(name);
|
||||
}
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
types::StackTypeSet *types = script()->analysis()->bytecodeTypes(pc);
|
||||
bool barrier = PropertyReadNeedsTypeBarrier(cx, globalType, name, types);
|
||||
|
||||
// If the property is permanent, a shape guard isn't necessary.
|
||||
@ -6001,14 +5995,14 @@ IonBuilder::jsop_getname(HandlePropertyName name)
|
||||
if (!resumeAfter(ins))
|
||||
return false;
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
types::StackTypeSet *types = script()->analysis()->bytecodeTypes(pc);
|
||||
return pushTypeBarrier(ins, types, true);
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::jsop_intrinsic(HandlePropertyName name)
|
||||
{
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
types::StackTypeSet *types = script()->analysis()->bytecodeTypes(pc);
|
||||
JSValueType type = types->getKnownTypeTag();
|
||||
|
||||
// If we haven't executed this opcode yet, we need to get the intrinsic
|
||||
@ -6104,7 +6098,7 @@ IonBuilder::jsop_getelem()
|
||||
|
||||
MInstruction *ins;
|
||||
|
||||
bool cacheable = obj->mightBeType(MIRType_Object) && !obj->mightBeType(MIRType_String) &&
|
||||
bool cacheable = obj->type() == MIRType_Object &&
|
||||
(index->mightBeType(MIRType_Int32) || index->mightBeType(MIRType_String));
|
||||
|
||||
// Turn off cacheing if the element is int32 and we've seen non-native objects as the target
|
||||
@ -6112,7 +6106,7 @@ IonBuilder::jsop_getelem()
|
||||
if (index->mightBeType(MIRType_Int32) && script()->analysis()->getCode(pc).nonNativeGetElement)
|
||||
cacheable = false;
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
types::StackTypeSet *types = script()->analysis()->bytecodeTypes(pc);
|
||||
bool barrier = PropertyReadNeedsTypeBarrier(cx, obj, NULL, types);
|
||||
|
||||
// Always add a barrier if the index might be a string, so that the cache
|
||||
@ -6150,7 +6144,7 @@ IonBuilder::jsop_getelem_dense()
|
||||
MDefinition *id = current->pop();
|
||||
MDefinition *obj = current->pop();
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
types::StackTypeSet *types = script()->analysis()->bytecodeTypes(pc);
|
||||
bool barrier = PropertyReadNeedsTypeBarrier(cx, obj, NULL, types);
|
||||
bool needsHoleCheck = !ElementAccessIsPacked(cx, obj);
|
||||
|
||||
@ -6338,7 +6332,7 @@ IonBuilder::jsop_getelem_typed(int arrayType)
|
||||
if (staticAccess)
|
||||
return true;
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
types::StackTypeSet *types = script()->analysis()->bytecodeTypes(pc);
|
||||
|
||||
MDefinition *id = current->pop();
|
||||
MDefinition *obj = current->pop();
|
||||
@ -6505,15 +6499,11 @@ IonBuilder::jsop_setelem_dense(types::StackTypeSet::DoubleConversion conversion,
|
||||
MElements *elements = MElements::New(obj);
|
||||
current->add(elements);
|
||||
|
||||
bool writeHole = script()->analysis()->getCode(pc).arrayWriteHole;
|
||||
SetElemICInspector icInspect(inspector->setElemICInspector(pc));
|
||||
writeHole |= icInspect.sawOOBDenseWrite();
|
||||
|
||||
// Use MStoreElementHole if this SETELEM has written to out-of-bounds
|
||||
// indexes in the past. Otherwise, use MStoreElement so that we can hoist
|
||||
// the initialized length and bounds check.
|
||||
MStoreElementCommon *store;
|
||||
if (writeHole && writeOutOfBounds) {
|
||||
if (script()->analysis()->getCode(pc).arrayWriteHole && writeOutOfBounds) {
|
||||
MStoreElementHole *ins = MStoreElementHole::New(obj, elements, id, newValue);
|
||||
store = ins;
|
||||
|
||||
@ -6654,7 +6644,7 @@ IonBuilder::jsop_length()
|
||||
bool
|
||||
IonBuilder::jsop_length_fastPath()
|
||||
{
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
types::StackTypeSet *types = script()->analysis()->bytecodeTypes(pc);
|
||||
|
||||
if (types->getKnownTypeTag() != JSVAL_TYPE_INT32)
|
||||
return false;
|
||||
@ -6758,7 +6748,7 @@ IonBuilder::jsop_arguments_getelem()
|
||||
current->add(load);
|
||||
current->push(load);
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
types::StackTypeSet *types = script()->analysis()->bytecodeTypes(pc);
|
||||
return pushTypeBarrier(load, types, true);
|
||||
}
|
||||
|
||||
@ -7172,7 +7162,7 @@ IonBuilder::jsop_getprop(HandlePropertyName name)
|
||||
|
||||
bool emitted = false;
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
types::StackTypeSet *types = script()->analysis()->bytecodeTypes(pc);
|
||||
|
||||
// Try to optimize arguments.length.
|
||||
if (!getPropTryArgumentsLength(&emitted) || emitted)
|
||||
@ -7756,9 +7746,7 @@ IonBuilder::jsop_this()
|
||||
}
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::ThisTypes(script());
|
||||
if (types && (types->getKnownTypeTag() == JSVAL_TYPE_OBJECT ||
|
||||
(types->empty() && fp && fp.thisValue().isObject())))
|
||||
{
|
||||
if (types && types->getKnownTypeTag() == JSVAL_TYPE_OBJECT) {
|
||||
// This is safe, because if the entry type of |this| is an object, it
|
||||
// will necessarily be an object throughout the entire function. OSR
|
||||
// can introduce a phi, but this phi will be specialized.
|
||||
@ -7895,7 +7883,7 @@ IonBuilder::jsop_getaliasedvar(ScopeCoordinate sc)
|
||||
current->add(load);
|
||||
current->push(load);
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
types::StackTypeSet *types = script()->analysis()->bytecodeTypes(pc);
|
||||
return pushTypeBarrier(load, types, true);
|
||||
}
|
||||
|
||||
|
@ -435,9 +435,6 @@ HandleException(JSContext *cx, const IonFrameIterator &frame, ResumeFromExceptio
|
||||
break;
|
||||
}
|
||||
|
||||
case JSTRY_LOOP:
|
||||
break;
|
||||
|
||||
default:
|
||||
JS_NOT_REACHED("Invalid try note");
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ IonBuilder::inlineNativeCall(CallInfo &callInfo, JSNative native)
|
||||
types::StackTypeSet *
|
||||
IonBuilder::getInlineReturnTypeSet()
|
||||
{
|
||||
return types::TypeScript::BytecodeTypes(script(), pc);
|
||||
return script()->analysis()->bytecodeTypes(pc);
|
||||
}
|
||||
|
||||
MIRType
|
||||
|
@ -2737,7 +2737,7 @@ class MBitXor : public MBinaryBitwiseInstruction
|
||||
return this;
|
||||
}
|
||||
MDefinition *foldIfEqual() {
|
||||
return this;
|
||||
return MConstant::New(Int32Value(0));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -191,6 +191,10 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
|
||||
startcode->stackDepth = 0;
|
||||
codeArray[0] = startcode;
|
||||
|
||||
/* Number of JOF_TYPESET opcodes we have encountered. */
|
||||
unsigned nTypeSets = 0;
|
||||
types::TypeSet *typeArray = script_->types->typeArray();
|
||||
|
||||
unsigned offset, nextOffset = 0;
|
||||
while (nextOffset < length) {
|
||||
offset = nextOffset;
|
||||
@ -267,6 +271,22 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
|
||||
stackDepth += ndefs;
|
||||
}
|
||||
|
||||
/*
|
||||
* Assign an observed type set to each reachable JOF_TYPESET opcode.
|
||||
* This may be less than the number of type sets in the script if some
|
||||
* are unreachable, and may be greater in case the number of type sets
|
||||
* overflows a uint16_t. In the latter case a single type set will be
|
||||
* used for the observed types of all ops after the overflow.
|
||||
*/
|
||||
if ((js_CodeSpec[op].format & JOF_TYPESET) && cx->typeInferenceEnabled()) {
|
||||
if (nTypeSets < script_->nTypeSets) {
|
||||
code->observedTypes = typeArray[nTypeSets++].toStackTypeSet();
|
||||
} else {
|
||||
JS_ASSERT(nTypeSets == UINT16_MAX);
|
||||
code->observedTypes = typeArray[nTypeSets - 1].toStackTypeSet();
|
||||
}
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
|
||||
case JSOP_RETURN:
|
||||
@ -373,7 +393,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
|
||||
if (catchOffset > forwardCatch)
|
||||
forwardCatch = catchOffset;
|
||||
|
||||
if (tn->kind != JSTRY_ITER && tn->kind != JSTRY_LOOP) {
|
||||
if (tn->kind != JSTRY_ITER) {
|
||||
if (!addJump(cx, catchOffset, &nextOffset, &forwardJump, &forwardLoop, stackDepth))
|
||||
return;
|
||||
getCode(catchOffset).exceptionEntry = true;
|
||||
@ -1475,7 +1495,7 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
|
||||
if (startOffset == offset + 1) {
|
||||
unsigned catchOffset = startOffset + tn->length;
|
||||
|
||||
if (tn->kind != JSTRY_ITER && tn->kind != JSTRY_LOOP) {
|
||||
if (tn->kind != JSTRY_ITER) {
|
||||
checkBranchTarget(cx, catchOffset, branchTargets, values, stackDepth);
|
||||
checkExceptionTarget(cx, catchOffset, exceptionTargets);
|
||||
}
|
||||
|
@ -122,8 +122,13 @@ class Bytecode
|
||||
|
||||
private:
|
||||
|
||||
union {
|
||||
/* If this is a JOF_TYPESET opcode, index into the observed types for the op. */
|
||||
types::StackTypeSet *observedTypes;
|
||||
|
||||
/* If this is a JSOP_LOOPHEAD or JSOP_LOOPENTRY, information about the loop. */
|
||||
LoopAnalysis *loop;
|
||||
};
|
||||
|
||||
/* --------- Lifetime analysis --------- */
|
||||
|
||||
@ -881,6 +886,11 @@ class ScriptAnalysis
|
||||
return (cs->format & JOF_POST) && !popGuaranteed(pc);
|
||||
}
|
||||
|
||||
types::StackTypeSet *bytecodeTypes(const jsbytecode *pc) {
|
||||
JS_ASSERT(js_CodeSpec[*pc].format & JOF_TYPESET);
|
||||
return getCode(pc).observedTypes;
|
||||
}
|
||||
|
||||
const SSAValue &poppedValue(uint32_t offset, uint32_t which) {
|
||||
JS_ASSERT(offset < script_->length);
|
||||
JS_ASSERT(which < GetUseCount(script_, offset) +
|
||||
|
@ -1752,7 +1752,6 @@ struct JSContext : js::ContextFriendFields,
|
||||
#endif
|
||||
|
||||
inline bool typeInferenceEnabled() const;
|
||||
inline bool jaegerCompilationAllowed() const;
|
||||
|
||||
void updateJITEnabled();
|
||||
|
||||
|
@ -411,12 +411,6 @@ JSContext::typeInferenceEnabled() const
|
||||
return compartment->zone()->types.inferenceEnabled;
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSContext::jaegerCompilationAllowed() const
|
||||
{
|
||||
return compartment->zone()->types.jaegerCompilationAllowed;
|
||||
}
|
||||
|
||||
inline js::Handle<js::GlobalObject*>
|
||||
JSContext::global() const
|
||||
{
|
||||
|
@ -1274,7 +1274,7 @@ PropertyAccess(JSContext *cx, JSScript *script, jsbytecode *pc, TypeObject *obje
|
||||
target->addSubset(cx, types);
|
||||
} else {
|
||||
JS_ASSERT_IF(script->hasAnalysis(),
|
||||
target == TypeScript::BytecodeTypes(script, pc));
|
||||
target == script->analysis()->bytecodeTypes(pc));
|
||||
if (!types->hasPropagatedProperty())
|
||||
object->getFromPrototypes(cx, id, types);
|
||||
if (UsePropertyTypeBarrier(pc)) {
|
||||
@ -1421,7 +1421,7 @@ TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type)
|
||||
jsbytecode *pc = callsite->pc;
|
||||
|
||||
JS_ASSERT_IF(script->hasAnalysis(),
|
||||
callsite->returnTypes == TypeScript::BytecodeTypes(script, pc));
|
||||
callsite->returnTypes == script->analysis()->bytecodeTypes(pc));
|
||||
|
||||
if (type.isUnknown() || type.isAnyObject()) {
|
||||
/* Monitor calls on unknown functions. */
|
||||
@ -2467,12 +2467,10 @@ TypeZone::init(JSContext *cx)
|
||||
!cx->hasOption(JSOPTION_TYPE_INFERENCE) ||
|
||||
!cx->runtime->jitSupportsFloatingPoint)
|
||||
{
|
||||
jaegerCompilationAllowed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
inferenceEnabled = true;
|
||||
jaegerCompilationAllowed = cx->hasOption(JSOPTION_METHODJIT);
|
||||
}
|
||||
|
||||
TypeObject *
|
||||
@ -2694,28 +2692,13 @@ types::UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
if (key != JSProto_Object && !(key >= JSProto_Int8Array && key <= JSProto_Uint8ClampedArray))
|
||||
return GenericObject;
|
||||
|
||||
/*
|
||||
* All loops in the script will have a JSTRY_ITER or JSTRY_LOOP try note
|
||||
* indicating their boundary.
|
||||
*/
|
||||
AutoEnterAnalysis enter(cx);
|
||||
|
||||
if (!script->hasTrynotes())
|
||||
return SingletonObject;
|
||||
|
||||
unsigned offset = pc - script->code;
|
||||
|
||||
JSTryNote *tn = script->trynotes()->vector;
|
||||
JSTryNote *tnlimit = tn + script->trynotes()->length;
|
||||
for (; tn < tnlimit; tn++) {
|
||||
if (tn->kind != JSTRY_ITER && tn->kind != JSTRY_LOOP)
|
||||
continue;
|
||||
|
||||
unsigned startOffset = script->mainOffset + tn->start;
|
||||
unsigned endOffset = startOffset + tn->length;
|
||||
|
||||
if (offset >= startOffset && offset < endOffset)
|
||||
if (!script->ensureRanAnalysis(cx))
|
||||
return GenericObject;
|
||||
|
||||
if (script->analysis()->getCode(pc).inLoop)
|
||||
return GenericObject;
|
||||
}
|
||||
|
||||
return SingletonObject;
|
||||
}
|
||||
@ -4314,7 +4297,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, TypeInferen
|
||||
case JSOP_CALLGNAME: {
|
||||
jsid id = GetAtomId(cx, script, pc, 0);
|
||||
|
||||
StackTypeSet *seen = TypeScript::BytecodeTypes(script, pc);
|
||||
StackTypeSet *seen = bytecodeTypes(pc);
|
||||
seen->addSubset(cx, &pushed[0]);
|
||||
|
||||
/*
|
||||
@ -4346,7 +4329,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, TypeInferen
|
||||
case JSOP_GETINTRINSIC:
|
||||
case JSOP_CALLNAME:
|
||||
case JSOP_CALLINTRINSIC: {
|
||||
StackTypeSet *seen = TypeScript::BytecodeTypes(script, pc);
|
||||
StackTypeSet *seen = bytecodeTypes(pc);
|
||||
addTypeBarrier(cx, pc, seen, Type::UnknownType());
|
||||
seen->addSubset(cx, &pushed[0]);
|
||||
break;
|
||||
@ -4375,7 +4358,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, TypeInferen
|
||||
break;
|
||||
|
||||
case JSOP_GETXPROP: {
|
||||
StackTypeSet *seen = TypeScript::BytecodeTypes(script, pc);
|
||||
StackTypeSet *seen = bytecodeTypes(pc);
|
||||
addTypeBarrier(cx, pc, seen, Type::UnknownType());
|
||||
seen->addSubset(cx, &pushed[0]);
|
||||
break;
|
||||
@ -4429,7 +4412,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, TypeInferen
|
||||
* there is little benefit to maintaining a TypeSet for the aliased
|
||||
* variable. Instead, we monitor/barrier all reads unconditionally.
|
||||
*/
|
||||
TypeScript::BytecodeTypes(script, pc)->addSubset(cx, &pushed[0]);
|
||||
bytecodeTypes(pc)->addSubset(cx, &pushed[0]);
|
||||
break;
|
||||
|
||||
case JSOP_SETALIASEDVAR:
|
||||
@ -4445,7 +4428,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, TypeInferen
|
||||
break;
|
||||
|
||||
case JSOP_REST: {
|
||||
StackTypeSet *types = TypeScript::BytecodeTypes(script, pc);
|
||||
StackTypeSet *types = script->analysis()->bytecodeTypes(pc);
|
||||
if (script->compileAndGo) {
|
||||
TypeObject *rest = TypeScript::InitObject(cx, script, pc, JSProto_Array);
|
||||
if (!rest)
|
||||
@ -4479,7 +4462,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, TypeInferen
|
||||
case JSOP_GETPROP:
|
||||
case JSOP_CALLPROP: {
|
||||
jsid id = GetAtomId(cx, script, pc, 0);
|
||||
StackTypeSet *seen = TypeScript::BytecodeTypes(script, pc);
|
||||
StackTypeSet *seen = script->analysis()->bytecodeTypes(pc);
|
||||
|
||||
HeapTypeSet *input = &script->types->propertyReadTypes[state.propertyReadIndex++];
|
||||
poppedTypes(pc, 0)->addSubset(cx, input);
|
||||
@ -4508,7 +4491,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, TypeInferen
|
||||
|
||||
case JSOP_GETELEM:
|
||||
case JSOP_CALLELEM: {
|
||||
StackTypeSet *seen = TypeScript::BytecodeTypes(script, pc);
|
||||
StackTypeSet *seen = script->analysis()->bytecodeTypes(pc);
|
||||
|
||||
/* Don't try to compute a precise callee for CALLELEM. */
|
||||
if (op == JSOP_CALLELEM)
|
||||
@ -4596,7 +4579,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, TypeInferen
|
||||
case JSOP_FUNCALL:
|
||||
case JSOP_FUNAPPLY:
|
||||
case JSOP_NEW: {
|
||||
StackTypeSet *seen = TypeScript::BytecodeTypes(script, pc);
|
||||
StackTypeSet *seen = script->analysis()->bytecodeTypes(pc);
|
||||
seen->addSubset(cx, &pushed[0]);
|
||||
|
||||
/* Construct the base call information about this site. */
|
||||
@ -4644,7 +4627,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, TypeInferen
|
||||
case JSOP_NEWINIT:
|
||||
case JSOP_NEWARRAY:
|
||||
case JSOP_NEWOBJECT: {
|
||||
StackTypeSet *types = TypeScript::BytecodeTypes(script, pc);
|
||||
StackTypeSet *types = script->analysis()->bytecodeTypes(pc);
|
||||
types->addSubset(cx, &pushed[0]);
|
||||
|
||||
bool isArray = (op == JSOP_NEWARRAY || (op == JSOP_NEWINIT && GET_UINT8(pc) == JSProto_Array));
|
||||
@ -4877,9 +4860,6 @@ ScriptAnalysis::analyzeTypes(JSContext *cx)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!script_->ensureHasBytecodeTypeMap(cx))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Set this early to avoid reentrance. Any failures are OOMs, and will nuke
|
||||
* all types in the compartment.
|
||||
@ -5289,7 +5269,7 @@ AnalyzePoppedThis(JSContext *cx, SSAUseChain *use,
|
||||
Shape *shape = type->proto ? type->proto->nativeLookup(cx, id) : NULL;
|
||||
if (shape && shape->hasSlot()) {
|
||||
Value protov = type->proto->getSlot(shape->slot());
|
||||
TypeSet *types = TypeScript::BytecodeTypes(script, pc);
|
||||
TypeSet *types = script->analysis()->bytecodeTypes(pc);
|
||||
types->addType(cx, GetValueType(cx, protov));
|
||||
}
|
||||
|
||||
@ -5581,7 +5561,7 @@ ScriptAnalysis::printTypes(JSContext *cx)
|
||||
continue;
|
||||
|
||||
if (js_CodeSpec[*pc].format & JOF_TYPESET) {
|
||||
TypeSet *types = TypeScript::BytecodeTypes(script_, pc);
|
||||
TypeSet *types = script_->analysis()->bytecodeTypes(pc);
|
||||
printf(" typeset %d:", (int) (types - script_->types->typeArray()));
|
||||
types->print();
|
||||
printf("\n");
|
||||
@ -5633,11 +5613,6 @@ types::MarkIteratorUnknownSlow(JSContext *cx)
|
||||
|
||||
AutoEnterAnalysis enter(cx);
|
||||
|
||||
if (!script->ensureHasTypes(cx)) {
|
||||
cx->compartment->types.setPendingNukeTypes(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This script is iterating over an actual Iterator or Generator object, or
|
||||
* an object with a custom __iterator__ hook. In such cases 'for in' loops
|
||||
@ -5721,16 +5696,15 @@ void
|
||||
types::TypeDynamicResult(JSContext *cx, JSScript *script, jsbytecode *pc, Type type)
|
||||
{
|
||||
JS_ASSERT(cx->typeInferenceEnabled());
|
||||
|
||||
AutoEnterAnalysis enter(cx);
|
||||
|
||||
/* Directly update associated type sets for applicable bytecodes. */
|
||||
if (js_CodeSpec[*pc].format & JOF_TYPESET) {
|
||||
if (!script->ensureHasBytecodeTypeMap(cx)) {
|
||||
if (!script->ensureRanAnalysis(cx)) {
|
||||
cx->compartment->types.setPendingNukeTypes(cx);
|
||||
return;
|
||||
}
|
||||
TypeSet *types = TypeScript::BytecodeTypes(script, pc);
|
||||
TypeSet *types = script->analysis()->bytecodeTypes(pc);
|
||||
if (!types->hasType(type)) {
|
||||
InferSpew(ISpewOps, "externalType: monitorResult #%u:%05u: %s",
|
||||
script->id(), pc - script->code, TypeString(type));
|
||||
@ -5829,13 +5803,13 @@ types::TypeMonitorResult(JSContext *cx, JSScript *script, jsbytecode *pc, const
|
||||
|
||||
AutoEnterAnalysis enter(cx);
|
||||
|
||||
if (!script->ensureHasBytecodeTypeMap(cx)) {
|
||||
if (!script->ensureRanAnalysis(cx)) {
|
||||
cx->compartment->types.setPendingNukeTypes(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
Type type = GetValueType(cx, rval);
|
||||
TypeSet *types = TypeScript::BytecodeTypes(script, pc);
|
||||
TypeSet *types = script->analysis()->bytecodeTypes(pc);
|
||||
if (types->hasType(type))
|
||||
return;
|
||||
|
||||
@ -5932,7 +5906,7 @@ JSScript::makeTypes(JSContext *cx)
|
||||
return false;
|
||||
}
|
||||
new(types) TypeScript();
|
||||
return analyzedArgsUsage() || ensureRanAnalysis(cx);
|
||||
return true;
|
||||
}
|
||||
|
||||
AutoEnterAnalysis enter(cx);
|
||||
@ -6002,36 +5976,6 @@ JSScript::makeTypes(JSContext *cx)
|
||||
}
|
||||
#endif
|
||||
|
||||
return analyzedArgsUsage() || ensureRanAnalysis(cx);
|
||||
}
|
||||
|
||||
bool
|
||||
JSScript::makeBytecodeTypeMap(JSContext *cx)
|
||||
{
|
||||
JS_ASSERT(cx->typeInferenceEnabled());
|
||||
JS_ASSERT(types && !types->bytecodeMap);
|
||||
|
||||
types->bytecodeMap = cx->analysisLifoAlloc().newArrayUninitialized<uint32_t>(nTypeSets + 1);
|
||||
|
||||
if (!types->bytecodeMap)
|
||||
return false;
|
||||
|
||||
uint32_t added = 0;
|
||||
for (jsbytecode *pc = code; pc < code + length; pc += GetBytecodeLength(pc)) {
|
||||
JSOp op = JSOp(*pc);
|
||||
if (js_CodeSpec[op].format & JOF_TYPESET) {
|
||||
types->bytecodeMap[added++] = pc - code;
|
||||
if (added == nTypeSets)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
JS_ASSERT(added == nTypeSets);
|
||||
|
||||
// The last entry in the last index found, and is used to avoid binary
|
||||
// searches for the sought entry when queries are in linear order.
|
||||
types->bytecodeMap[nTypeSets] = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1177,12 +1177,6 @@ class TypeScript
|
||||
/* Analysis information for the script, cleared on each GC. */
|
||||
analyze::ScriptAnalysis *analysis;
|
||||
|
||||
/*
|
||||
* List mapping indexes of bytecode type sets to the offset of the opcode
|
||||
* they correspond to. Cleared on each GC.
|
||||
*/
|
||||
uint32_t *bytecodeMap;
|
||||
|
||||
public:
|
||||
/* Dynamic types generated at points within this script. */
|
||||
TypeResult *dynamicList;
|
||||
@ -1207,9 +1201,6 @@ class TypeScript
|
||||
/* Follows slot layout in jsanalyze.h, can get this/arg/local type sets. */
|
||||
static inline StackTypeSet *SlotTypes(JSScript *script, unsigned slot);
|
||||
|
||||
/* Get the type set for values observed at an opcode. */
|
||||
static inline StackTypeSet *BytecodeTypes(JSScript *script, jsbytecode *pc);
|
||||
|
||||
/* Get the default 'new' object for a given standard class, per the script's global. */
|
||||
static inline TypeObject *StandardType(JSContext *cx, JSProtoKey kind);
|
||||
|
||||
@ -1475,13 +1466,6 @@ struct TypeZone
|
||||
/* Whether type inference is enabled in this compartment. */
|
||||
bool inferenceEnabled;
|
||||
|
||||
/*
|
||||
* JM compilation is allowed only if script analysis has been used to
|
||||
* monitor the behavior of all scripts in this zone since its creation.
|
||||
* OSR in JM requires this property.
|
||||
*/
|
||||
bool jaegerCompilationAllowed;
|
||||
|
||||
TypeZone(JS::Zone *zone);
|
||||
~TypeZone();
|
||||
void init(JSContext *cx);
|
||||
|
@ -586,7 +586,7 @@ TypeMonitorCall(JSContext *cx, const js::CallArgs &args, bool constructing)
|
||||
if (args.callee().isFunction()) {
|
||||
JSFunction *fun = args.callee().toFunction();
|
||||
if (fun->isInterpreted()) {
|
||||
if (!fun->nonLazyScript()->ensureHasTypes(cx))
|
||||
if (!fun->nonLazyScript()->ensureRanAnalysis(cx))
|
||||
return false;
|
||||
if (cx->typeInferenceEnabled())
|
||||
TypeMonitorCallSlow(cx, &args.callee(), args, constructing);
|
||||
@ -858,49 +858,6 @@ TypeScript::SlotTypes(JSScript *script, unsigned slot)
|
||||
return types->toStackTypeSet();
|
||||
}
|
||||
|
||||
/* static */ inline StackTypeSet *
|
||||
TypeScript::BytecodeTypes(JSScript *script, jsbytecode *pc)
|
||||
{
|
||||
JS_ASSERT(js_CodeSpec[*pc].format & JOF_TYPESET);
|
||||
JS_ASSERT(script->types && script->types->bytecodeMap);
|
||||
uint32_t *bytecodeMap = script->types->bytecodeMap;
|
||||
uint32_t *hint = bytecodeMap + script->nTypeSets;
|
||||
uint32_t offset = pc - script->code;
|
||||
JS_ASSERT(offset < script->length);
|
||||
|
||||
// See if this pc is the next typeset opcode after the last one looked up.
|
||||
if (bytecodeMap[*hint + 1] == offset && (*hint + 1) < script->nTypeSets) {
|
||||
(*hint)++;
|
||||
return script->types->typeArray()->toStackTypeSet() + *hint;
|
||||
}
|
||||
|
||||
// See if this pc is the same as the last one looked up.
|
||||
if (bytecodeMap[*hint] == offset)
|
||||
return script->types->typeArray()->toStackTypeSet() + *hint;
|
||||
|
||||
// Fall back to a binary search.
|
||||
size_t bottom = 0;
|
||||
size_t top = script->nTypeSets - 1;
|
||||
size_t mid = (bottom + top) / 2;
|
||||
while (mid < top) {
|
||||
if (bytecodeMap[mid] < offset)
|
||||
bottom = mid + 1;
|
||||
else if (bytecodeMap[mid] > offset)
|
||||
top = mid;
|
||||
else
|
||||
break;
|
||||
mid = (bottom + top) / 2;
|
||||
}
|
||||
|
||||
// We should have have zeroed in on either the exact offset, unless there
|
||||
// are more JOF_TYPESET opcodes than nTypeSets in the script (as can happen
|
||||
// if the script is very long).
|
||||
JS_ASSERT(bytecodeMap[mid] == offset || mid == top);
|
||||
|
||||
*hint = mid;
|
||||
return script->types->typeArray()->toStackTypeSet() + *hint;
|
||||
}
|
||||
|
||||
/* static */ inline TypeObject *
|
||||
TypeScript::StandardType(JSContext *cx, JSProtoKey key)
|
||||
{
|
||||
@ -1825,12 +1782,6 @@ JSScript::ensureHasTypes(JSContext *cx)
|
||||
return types || makeTypes(cx);
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSScript::ensureHasBytecodeTypeMap(JSContext *cx)
|
||||
{
|
||||
return ensureHasTypes(cx) && (types->bytecodeMap || makeBytecodeTypeMap(cx));
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSScript::ensureRanAnalysis(JSContext *cx)
|
||||
{
|
||||
@ -1872,10 +1823,8 @@ JSScript::analysis()
|
||||
inline void
|
||||
JSScript::clearAnalysis()
|
||||
{
|
||||
if (types) {
|
||||
if (types)
|
||||
types->analysis = NULL;
|
||||
types->bytecodeMap = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
|
@ -565,7 +565,7 @@ js::ExecuteKernel(JSContext *cx, HandleScript script, JSObject &scopeChainArg, c
|
||||
if (!cx->stack.pushExecuteFrame(cx, script, thisv, scopeChain, type, evalInFrame, &efg))
|
||||
return false;
|
||||
|
||||
if (!script->ensureHasTypes(cx))
|
||||
if (!script->ensureRanAnalysis(cx))
|
||||
return false;
|
||||
TypeScript::SetThis(cx, script, efg.fp()->thisValue());
|
||||
|
||||
@ -3366,11 +3366,7 @@ END_CASE(JSOP_ARRAYPUSH)
|
||||
regs.sp -= 1;
|
||||
if (!ok)
|
||||
goto error;
|
||||
break;
|
||||
}
|
||||
|
||||
case JSTRY_LOOP:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1520,9 +1520,7 @@ js::CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject
|
||||
}
|
||||
|
||||
if (res && cx->typeInferenceEnabled()) {
|
||||
JSScript *script = callee->toFunction()->nonLazyScript();
|
||||
if (!script->ensureHasTypes(cx))
|
||||
return NULL;
|
||||
RootedScript script(cx, callee->toFunction()->nonLazyScript());
|
||||
TypeScript::SetThis(cx, script, types::Type::ObjectType(res));
|
||||
}
|
||||
|
||||
@ -1549,9 +1547,7 @@ js::CreateThisForFunction(JSContext *cx, HandleObject callee, bool newType)
|
||||
/* Reshape the singleton before passing it as the 'this' value. */
|
||||
JSObject::clear(cx, nobj);
|
||||
|
||||
JSScript *calleeScript = callee->toFunction()->nonLazyScript();
|
||||
if (!calleeScript->ensureHasTypes(cx))
|
||||
return NULL;
|
||||
RootedScript calleeScript(cx, callee->toFunction()->nonLazyScript());
|
||||
TypeScript::SetThis(cx, calleeScript, types::Type::ObjectType(nobj));
|
||||
|
||||
return nobj;
|
||||
|
@ -49,15 +49,12 @@ namespace analyze {
|
||||
|
||||
/*
|
||||
* Type of try note associated with each catch or finally block, and also with
|
||||
* for-in and other kinds of loops. Non-for-in loops do not need these notes
|
||||
* for exception unwinding, but storing their boundaries here is helpful for
|
||||
* heuristics that need to know whether a given op is inside a loop.
|
||||
* for-in loops.
|
||||
*/
|
||||
typedef enum JSTryNoteKind {
|
||||
JSTRY_CATCH,
|
||||
JSTRY_FINALLY,
|
||||
JSTRY_ITER,
|
||||
JSTRY_LOOP
|
||||
JSTRY_ITER
|
||||
} JSTryNoteKind;
|
||||
|
||||
/*
|
||||
@ -67,9 +64,9 @@ struct JSTryNote {
|
||||
uint8_t kind; /* one of JSTryNoteKind */
|
||||
uint8_t padding; /* explicit padding on uint16_t boundary */
|
||||
uint16_t stackDepth; /* stack depth upon exception handler entry */
|
||||
uint32_t start; /* start of the try statement or loop
|
||||
uint32_t start; /* start of the try statement or for-in loop
|
||||
relative to script->main */
|
||||
uint32_t length; /* length of the try statement or loop */
|
||||
uint32_t length; /* length of the try statement or for-in loop */
|
||||
};
|
||||
|
||||
namespace js {
|
||||
@ -720,9 +717,6 @@ class JSScript : public js::gc::Cell
|
||||
/* Ensure the script has a TypeScript. */
|
||||
inline bool ensureHasTypes(JSContext *cx);
|
||||
|
||||
/* Ensure the script has a TypeScript and map for computing BytecodeTypes. */
|
||||
inline bool ensureHasBytecodeTypeMap(JSContext *cx);
|
||||
|
||||
/*
|
||||
* Ensure the script has bytecode analysis information. Performed when the
|
||||
* script first runs, or first runs after a TypeScript GC purge.
|
||||
@ -764,7 +758,6 @@ class JSScript : public js::gc::Cell
|
||||
|
||||
private:
|
||||
bool makeTypes(JSContext *cx);
|
||||
bool makeBytecodeTypeMap(JSContext *cx);
|
||||
bool makeAnalysis(JSContext *cx);
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
|
@ -121,8 +121,6 @@ mjit::Compiler::Compiler(JSContext *cx, JSScript *outerScript,
|
||||
gcNumber(cx->runtime->gcNumber),
|
||||
pcLengths(NULL)
|
||||
{
|
||||
JS_ASSERT(cx->jaegerCompilationAllowed());
|
||||
|
||||
if (!IsIonEnabled(cx)) {
|
||||
/* Once a script starts getting really hot we will inline calls in it. */
|
||||
if (!debugMode() && cx->typeInferenceEnabled() && globalObj &&
|
||||
@ -996,9 +994,6 @@ mjit::CanMethodJIT(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
if (!cx->methodJitEnabled)
|
||||
return Compile_Abort;
|
||||
|
||||
if (!cx->jaegerCompilationAllowed())
|
||||
return Compile_Abort;
|
||||
|
||||
#ifdef JS_ION
|
||||
if (ion::IsBaselineEnabled(cx) || ion::IsEnabled(cx))
|
||||
return Compile_Abort;
|
||||
@ -8128,7 +8123,7 @@ mjit::Compiler::testBarrier(RegisterID typeReg, RegisterID dataReg,
|
||||
if (!cx->typeInferenceEnabled() || !(js_CodeSpec[*PC].format & JOF_TYPESET))
|
||||
return state;
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script_, PC);
|
||||
types::StackTypeSet *types = analysis->bytecodeTypes(PC);
|
||||
if (types->unknown()) {
|
||||
/*
|
||||
* If the result of this opcode is already unknown, there is no way for
|
||||
@ -8193,7 +8188,7 @@ mjit::Compiler::testPushedType(RejoinState rejoin, int which, bool ool)
|
||||
if (!cx->typeInferenceEnabled() || !(js_CodeSpec[*PC].format & JOF_TYPESET))
|
||||
return;
|
||||
|
||||
types::TypeSet *types = types::TypeScript::BytecodeTypes(script_, PC);
|
||||
types::TypeSet *types = analysis->bytecodeTypes(PC);
|
||||
if (types->unknown())
|
||||
return;
|
||||
|
||||
|
@ -115,11 +115,7 @@ FindExceptionHandler(JSContext *cx)
|
||||
cx->regs().sp -= 1;
|
||||
if (!ok)
|
||||
goto error;
|
||||
break;
|
||||
}
|
||||
|
||||
case JSTRY_LOOP:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -437,7 +437,7 @@ mjit::NativeStubEpilogue(VMFrame &f, Assembler &masm, NativeStubLinker::FinalJum
|
||||
* the call. We don't assume knowledge about the types that natives can
|
||||
* return, except when generating specialized paths in FastBuiltins.
|
||||
*/
|
||||
types::TypeSet *types = types::TypeScript::BytecodeTypes(f.script(), f.pc());
|
||||
types::TypeSet *types = f.script()->analysis()->bytecodeTypes(f.pc());
|
||||
if (!masm.generateTypeCheck(f.cx, resultAddress, types, &mismatches))
|
||||
THROWV(false);
|
||||
}
|
||||
|
@ -1809,7 +1809,7 @@ JS_STATIC_ASSERT(JSTRY_CATCH == 0);
|
||||
JS_STATIC_ASSERT(JSTRY_FINALLY == 1);
|
||||
JS_STATIC_ASSERT(JSTRY_ITER == 2);
|
||||
|
||||
static const char* const TryNoteNames[] = { "catch", "finally", "iter", "loop" };
|
||||
static const char* const TryNoteNames[] = { "catch", "finally", "iter" };
|
||||
|
||||
static JSBool
|
||||
TryNotes(JSContext *cx, HandleScript script, Sprinter *sp)
|
||||
@ -4927,6 +4927,11 @@ ProcessArgs(JSContext *cx, JSObject *obj_, OptionParser *op)
|
||||
if (op->getBoolOption('s'))
|
||||
JS_ToggleOptions(cx, JSOPTION_STRICT);
|
||||
|
||||
if (op->getBoolOption("no-jm")) {
|
||||
enableMethodJit = false;
|
||||
JS_ToggleOptions(cx, JSOPTION_METHODJIT);
|
||||
}
|
||||
|
||||
if (op->getBoolOption('d')) {
|
||||
JS_SetRuntimeDebugMode(JS_GetRuntime(cx), true);
|
||||
JS_SetDebugMode(cx, true);
|
||||
@ -5116,17 +5121,13 @@ Shell(JSContext *cx, OptionParser *op, char **envp)
|
||||
JSAutoRequest ar(cx);
|
||||
|
||||
/*
|
||||
* First check to see if type inference and JM are enabled. These flags
|
||||
* must be set on the compartment when it is constructed.
|
||||
* First check to see if type inference is enabled. This flag must be set
|
||||
* on the compartment when it is constructed.
|
||||
*/
|
||||
if (op->getBoolOption("no-ti")) {
|
||||
enableTypeInference = false;
|
||||
JS_ToggleOptions(cx, JSOPTION_TYPE_INFERENCE);
|
||||
}
|
||||
if (op->getBoolOption("no-jm")) {
|
||||
enableMethodJit = false;
|
||||
JS_ToggleOptions(cx, JSOPTION_METHODJIT);
|
||||
}
|
||||
|
||||
RootedObject glob(cx);
|
||||
glob = NewGlobalObject(cx, NULL);
|
||||
|
@ -26,7 +26,7 @@ namespace js {
|
||||
* and saved versions. If deserialization fails, the data should be
|
||||
* invalidated if possible.
|
||||
*/
|
||||
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 142);
|
||||
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 141);
|
||||
|
||||
class XDRBuffer {
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user