#425: M1383645 M1383646 M1385459

This commit is contained in:
Cameron Kaiser 2017-08-12 12:12:38 -07:00
parent aad4dea917
commit fccfbd1224
6 changed files with 51 additions and 16 deletions

View File

@ -617,7 +617,7 @@ NativeRegExpMacroAssembler::Backtrack()
// Check for an interrupt.
Label noInterrupt;
masm.branch32(Assembler::Equal,
AbsoluteAddress(runtime->addressOfInterruptUint32()), Imm32(0),
AbsoluteAddress(runtime->addressOfInterruptRegExpJitUint32()), Imm32(0),
&noInterrupt);
masm.movePtr(ImmWord(RegExpRunStatus_Error), temp0);
masm.jump(&exit_label_);
@ -627,7 +627,7 @@ NativeRegExpMacroAssembler::Backtrack()
PopBacktrack(temp0);
masm.jump(temp0);
#else
masm.x_li32(addressTempRegister, (uint32_t)runtime->addressOfInterruptUint32());
masm.x_li32(addressTempRegister, (uint32_t)runtime->addressOfInterruptRegExpJitUint32());
masm.lwz(tempRegister, addressTempRegister, 0);
PPC_BC(noIRQ, tempRegister, Imm32(0), Equal);
masm.movePtr(ImmWord(RegExpRunStatus_Error), temp0);

View File

@ -0,0 +1,10 @@
var x = "abc";
assertEq(x.indexOf(x), 0);
assertEq(x.indexOf(x, -1), 0);
assertEq(x.indexOf(x, 1), -1);
assertEq(x.indexOf(x, 100), -1);
assertEq(x.lastIndexOf(x), 0);
assertEq(x.lastIndexOf(x, -1), 0);
assertEq(x.lastIndexOf(x, 1), 0);
assertEq(x.lastIndexOf(x, 100), 0);

View File

@ -2330,13 +2330,16 @@ IonBuilder::inlineUnsafeSetReservedSlot(CallInfo& callInfo)
}
if (getInlineReturnType() != MIRType_Undefined)
return InliningStatus_NotInlined;
if (callInfo.getArg(0)->type() != MIRType_Object)
MDefinition* obj = callInfo.getArg(0);
if (obj->type() != MIRType_Object && obj->type() != MIRType_Value)
return InliningStatus_NotInlined;
if (callInfo.getArg(1)->type() != MIRType_Int32)
MDefinition* arg = callInfo.getArg(1);
if (arg->type() != MIRType_Int32)
return InliningStatus_NotInlined;
// Don't inline if we don't have a constant slot.
MDefinition* arg = callInfo.getArg(1);
if (!arg->isConstantValue())
return InliningStatus_NotInlined;
uint32_t slot = arg->constantValue().toPrivateUint32();
@ -2344,12 +2347,12 @@ IonBuilder::inlineUnsafeSetReservedSlot(CallInfo& callInfo)
callInfo.setImplicitlyUsedUnchecked();
MStoreFixedSlot* store =
MStoreFixedSlot::NewBarriered(alloc(), callInfo.getArg(0), slot, callInfo.getArg(2));
MStoreFixedSlot::NewBarriered(alloc(), obj, slot, callInfo.getArg(2));
current->add(store);
current->push(store);
if (NeedsPostBarrier(callInfo.getArg(2)))
current->add(MPostWriteBarrier::New(alloc(), callInfo.getArg(0), callInfo.getArg(2)));
current->add(MPostWriteBarrier::New(alloc(), obj, callInfo.getArg(2)));
return InliningStatus_Inlined;
}
@ -2361,20 +2364,23 @@ IonBuilder::inlineUnsafeGetReservedSlot(CallInfo& callInfo, MIRType knownValueTy
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
return InliningStatus_NotInlined;
}
if (callInfo.getArg(0)->type() != MIRType_Object)
MDefinition* obj = callInfo.getArg(0);
if (obj->type() != MIRType_Object && obj->type() != MIRType_Value)
return InliningStatus_NotInlined;
if (callInfo.getArg(1)->type() != MIRType_Int32)
MDefinition* arg = callInfo.getArg(1);
if (arg->type() != MIRType_Int32)
return InliningStatus_NotInlined;
// Don't inline if we don't have a constant slot.
MDefinition* arg = callInfo.getArg(1);
if (!arg->isConstantValue())
return InliningStatus_NotInlined;
uint32_t slot = arg->constantValue().toPrivateUint32();
callInfo.setImplicitlyUsedUnchecked();
MLoadFixedSlot* load = MLoadFixedSlot::New(alloc(), callInfo.getArg(0), slot);
MLoadFixedSlot* load = MLoadFixedSlot::New(alloc(), obj, slot);
current->add(load);
current->push(load);
if (knownValueType != MIRType_Value) {

View File

@ -1596,6 +1596,13 @@ js::str_indexOf(JSContext* cx, unsigned argc, Value* vp)
// Step 9
uint32_t start = Min(Max(pos, 0U), textLen);
if (str == searchStr) {
// AngularJS often invokes "false".indexOf("false"). This check should
// be cheap enough to not hurt anything else.
args.rval().setInt32(start == 0 ? 0 : -1);
return true;
}
// Steps 10 and 11
JSLinearString* text = str->ensureLinear(cx);
if (!text)
@ -1646,6 +1653,11 @@ js::str_lastIndexOf(JSContext* cx, unsigned argc, Value* vp)
if (!pat)
return false;
if (textstr == pat) {
args.rval().setInt32(0);
return true;
}
size_t textLen = textstr->length();
size_t patLen = pat->length();
int start = textLen - patLen; // Start searching here

View File

@ -144,6 +144,7 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
entryMonitor(nullptr),
parentRuntime(parentRuntime),
interrupt_(false),
interruptRegExpJit_(false),
telemetryCallback(nullptr),
handlingSignal(false),
interruptCallback(nullptr),
@ -641,11 +642,11 @@ JSRuntime::requestInterrupt(InterruptMode mode)
jitStackLimit_ = UINTPTR_MAX;
if (mode == JSRuntime::RequestInterruptUrgent) {
// If this interrupt is urgent (slow script dialog and garbage
// collection among others), take additional steps to
// interrupt corner cases where the above fields are not
// regularly polled. Wake both ilooping JIT code and
// futexWait.
// If this interrupt is urgent (slow script dialog for instance), take
// additional steps to interrupt corner cases where the above fields are
// not regularly polled. Wake ilooping Ion code, irregexp JIT code and
// Atomics.wait()
interruptRegExpJit_ = true;
fx.lock();
if (fx.isWaiting())
fx.wake(FutexRuntime::WakeForJSInterrupt);
@ -660,6 +661,7 @@ JSRuntime::handleInterrupt(JSContext* cx)
MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
if (interrupt_ || jitStackLimit_ == UINTPTR_MAX) {
interrupt_ = false;
interruptRegExpJit_ = false;
resetJitStackLimit();
return InvokeInterruptCallback(cx);
}

View File

@ -794,6 +794,7 @@ struct JSRuntime : public JS::shadow::Runtime,
private:
mozilla::Atomic<uint32_t, mozilla::Relaxed> interrupt_;
mozilla::Atomic<uint32_t, mozilla::Relaxed> interruptRegExpJit_;
/* Call this to accumulate telemetry data. */
JSAccumulateTelemetryDataCallback telemetryCallback;
@ -841,6 +842,10 @@ struct JSRuntime : public JS::shadow::Runtime,
static_assert(sizeof(interrupt_) == sizeof(uint32_t), "Assumed by JIT callers");
return &interrupt_;
}
void* addressOfInterruptRegExpJitUint32() { // see bug 1386199
static_assert(sizeof(interruptRegExpJit_) == sizeof(uint32_t), "Assumed by JIT callers");
return &interruptRegExpJit_;
}
/* Set when handling a signal for a thread associated with this runtime. */
bool handlingSignal;