зеркало из https://github.com/mozilla/gecko-dev.git
Backout 95a4b87a0583 (bug 894948) for causing an octane-crypto regression on a CLOSED TREE
This commit is contained in:
Родитель
be6e80b946
Коммит
22e70403d7
|
@ -4173,7 +4173,7 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub,
|
|||
if (!InitArrayElemOperation(cx, pc, obj, index.toInt32(), rhs))
|
||||
return false;
|
||||
} else {
|
||||
if (!SetObjectElement(cx, obj, index, rhs, script->strict))
|
||||
if (!SetObjectElement(cx, obj, index, rhs, script->strict, script, pc))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -6326,6 +6326,15 @@ IonBuilder::jsop_getelem()
|
|||
bool cacheable = obj->mightBeType(MIRType_Object) && !obj->mightBeType(MIRType_String) &&
|
||||
(index->mightBeType(MIRType_Int32) || index->mightBeType(MIRType_String));
|
||||
|
||||
bool nonNativeGetElement =
|
||||
script()->analysis()->getCode(pc).nonNativeGetElement ||
|
||||
inspector->hasSeenNonNativeGetElement(pc);
|
||||
|
||||
// Turn off cacheing if the element is int32 and we've seen non-native objects as the target
|
||||
// of this getelem.
|
||||
if (index->mightBeType(MIRType_Int32) && nonNativeGetElement)
|
||||
cacheable = false;
|
||||
|
||||
types::StackTypeSet *types = types::TypeScript::BytecodeTypes(script(), pc);
|
||||
bool barrier = PropertyReadNeedsTypeBarrier(cx, obj, NULL, types);
|
||||
|
||||
|
@ -6838,8 +6847,14 @@ IonBuilder::jsop_setelem_dense(types::StackTypeSet::DoubleConversion conversion,
|
|||
MOZ_ASSUME_UNREACHABLE("Unknown double conversion");
|
||||
}
|
||||
|
||||
bool writeHole = safety == SetElem_Normal &&
|
||||
inspector->setElemICInspector(pc).sawOOBDenseWrite();
|
||||
bool writeHole;
|
||||
if (safety == SetElem_Normal) {
|
||||
writeHole = script()->analysis()->getCode(pc).arrayWriteHole;
|
||||
SetElemICInspector icInspect(inspector->setElemICInspector(pc));
|
||||
writeHole |= icInspect.sawOOBDenseWrite();
|
||||
} else {
|
||||
writeHole = false;
|
||||
}
|
||||
|
||||
// Use MStoreElementHole if this SETELEM has written to out-of-bounds
|
||||
// indexes in the past. Otherwise, use MStoreElement so that we can hoist
|
||||
|
|
|
@ -103,6 +103,9 @@ class Bytecode
|
|||
* Dynamically observed state about the execution of this opcode. These are
|
||||
* hints about the script for use during compilation.
|
||||
*/
|
||||
bool arrayWriteHole: 1; /* SETELEM which has written to an array hole. */
|
||||
bool getStringElement:1; /* GETELEM which has accessed string properties. */
|
||||
bool nonNativeGetElement:1; /* GETELEM on a non-native, non-array object. */
|
||||
bool accessGetter: 1; /* Property read on a shape with a getter hook. */
|
||||
|
||||
/* Stack depth before this opcode. */
|
||||
|
|
|
@ -354,8 +354,20 @@ GetObjectElementOperation(JSContext *cx, JSOp op, JSObject *objArg, bool wasObje
|
|||
HandleValue rref, MutableHandleValue res)
|
||||
{
|
||||
do {
|
||||
// Don't call GetPcScript (needed for analysis) from inside Ion since it's expensive.
|
||||
bool analyze = cx->currentlyRunningInInterpreter();
|
||||
|
||||
uint32_t index;
|
||||
if (IsDefinitelyIndex(rref, &index)) {
|
||||
if (analyze && !objArg->isNative() && !objArg->is<TypedArrayObject>()) {
|
||||
JSScript *script = NULL;
|
||||
jsbytecode *pc = NULL;
|
||||
types::TypeScript::GetPcScript(cx, &script, &pc);
|
||||
|
||||
if (script->hasAnalysis())
|
||||
script->analysis()->getCode(pc).nonNativeGetElement = true;
|
||||
}
|
||||
|
||||
if (JSObject::getElementNoGC(cx, objArg, objArg, index, res.address()))
|
||||
break;
|
||||
|
||||
|
@ -366,6 +378,22 @@ GetObjectElementOperation(JSContext *cx, JSOp op, JSObject *objArg, bool wasObje
|
|||
break;
|
||||
}
|
||||
|
||||
if (analyze) {
|
||||
JSScript *script = NULL;
|
||||
jsbytecode *pc = NULL;
|
||||
types::TypeScript::GetPcScript(cx, &script, &pc);
|
||||
|
||||
if (script->hasAnalysis()) {
|
||||
script->analysis()->getCode(pc).getStringElement = true;
|
||||
|
||||
if (!objArg->is<ArrayObject>() && !objArg->isNative() &&
|
||||
!objArg->is<TypedArrayObject>())
|
||||
{
|
||||
script->analysis()->getCode(pc).nonNativeGetElement = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ValueMightBeSpecial(rref)) {
|
||||
RootedObject obj(cx, objArg);
|
||||
Rooted<SpecialId> special(cx);
|
||||
|
|
|
@ -1240,10 +1240,30 @@ ModOperation(JSContext *cx, HandleScript script, jsbytecode *pc, HandleValue lhs
|
|||
|
||||
static JS_ALWAYS_INLINE bool
|
||||
SetObjectElementOperation(JSContext *cx, Handle<JSObject*> obj, HandleId id, const Value &value,
|
||||
bool strict)
|
||||
bool strict, JSScript *maybeScript = NULL, jsbytecode *pc = NULL)
|
||||
{
|
||||
RootedScript script(cx, maybeScript);
|
||||
types::TypeScript::MonitorAssign(cx, obj, id);
|
||||
|
||||
if (obj->isNative() && JSID_IS_INT(id)) {
|
||||
uint32_t length = obj->getDenseInitializedLength();
|
||||
int32_t i = JSID_TO_INT(id);
|
||||
if ((uint32_t)i >= length) {
|
||||
// In an Ion activation, GetPcScript won't work. For non-baseline activations,
|
||||
// that's ok, because optimized ion doesn't generate analysis info. However,
|
||||
// baseline must generate this information, so it passes the script and pc in
|
||||
// as arguments.
|
||||
if (script || cx->currentlyRunningInInterpreter()) {
|
||||
JS_ASSERT(!!script == !!pc);
|
||||
if (!script)
|
||||
types::TypeScript::GetPcScript(cx, script.address(), &pc);
|
||||
|
||||
if (script->hasAnalysis())
|
||||
script->analysis()->getCode(pc).arrayWriteHole = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obj->isNative() && !obj->setHadElementsAccess(cx))
|
||||
return false;
|
||||
|
||||
|
@ -3696,6 +3716,17 @@ js::SetObjectElement(JSContext *cx, HandleObject obj, HandleValue index, HandleV
|
|||
return SetObjectElementOperation(cx, obj, id, value, strict);
|
||||
}
|
||||
|
||||
bool
|
||||
js::SetObjectElement(JSContext *cx, HandleObject obj, HandleValue index, HandleValue value,
|
||||
JSBool strict, HandleScript script, jsbytecode *pc)
|
||||
{
|
||||
JS_ASSERT(pc);
|
||||
RootedId id(cx);
|
||||
if (!ValueToId<CanGC>(cx, index, &id))
|
||||
return false;
|
||||
return SetObjectElementOperation(cx, obj, id, value, strict, script, pc);
|
||||
}
|
||||
|
||||
bool
|
||||
js::InitElementArray(JSContext *cx, jsbytecode *pc, HandleObject obj, uint32_t index, HandleValue value)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче