Loading js/src/builtin/RegExp.cpp +76 −37 Original line number Diff line number Diff line Loading @@ -1579,88 +1579,116 @@ js::RegExpPrototypeOptimizable(JSContext* cx, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 1); args.rval().setBoolean(RegExpPrototypeOptimizableRaw(cx, &args[0].toObject())); uint8_t result = false; if (!RegExpPrototypeOptimizableRaw(cx, &args[0].toObject(), &result)) return false; args.rval().setBoolean(result); return true; } bool js::RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto) js::RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto, uint8_t* result) { JS::AutoCheckCannotGC nogc; AutoAssertNoPendingException aanpe(cx); if (!proto->isNative()) return false; if (!proto->isNative()) { *result = false; return true; } NativeObject* nproto = static_cast<NativeObject*>(proto); Shape* shape = cx->compartment()->regExps.getOptimizableRegExpPrototypeShape(); if (shape == nproto->lastProperty()) if (shape == nproto->lastProperty()) { *result = true; return true; } JSFunction* flagsGetter; if (!GetOwnGetterPure(cx, proto, NameToId(cx->names().flags), &flagsGetter)) return false; if (!flagsGetter) return false; if (!flagsGetter) { *result = false; return true; } if (!IsSelfHostedFunctionWithName(flagsGetter, cx->names().RegExpFlagsGetter)) return false; if (!IsSelfHostedFunctionWithName(flagsGetter, cx->names().RegExpFlagsGetter)) { *result = false; return true; } JSNative globalGetter; if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().global), &globalGetter)) return false; if (globalGetter != regexp_global) return false; if (globalGetter != regexp_global) { *result = false; return true; } JSNative ignoreCaseGetter; if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().ignoreCase), &ignoreCaseGetter)) return false; if (ignoreCaseGetter != regexp_ignoreCase) return false; if (ignoreCaseGetter != regexp_ignoreCase) { *result = false; return true; } JSNative multilineGetter; if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().multiline), &multilineGetter)) return false; if (multilineGetter != regexp_multiline) return false; if (multilineGetter != regexp_multiline) { *result = false; return true; } JSNative stickyGetter; if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().sticky), &stickyGetter)) return false; if (stickyGetter != regexp_sticky) return false; if (stickyGetter != regexp_sticky) { *result = false; return true; } JSNative unicodeGetter; if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().unicode), &unicodeGetter)) return false; if (unicodeGetter != regexp_unicode) return false; if (unicodeGetter != regexp_unicode) { *result = false; return true; } // Check if @@match, @@search, and exec are own data properties, // those values should be tested in selfhosted JS. bool has = false; if (!HasOwnDataPropertyPure(cx, proto, SYMBOL_TO_JSID(cx->wellKnownSymbols().match), &has)) return false; if (!has) return false; if (!has) { *result = false; return true; } if (!HasOwnDataPropertyPure(cx, proto, SYMBOL_TO_JSID(cx->wellKnownSymbols().search), &has)) return false; if (!has) return false; if (!has) { *result = false; return true; } if (!HasOwnDataPropertyPure(cx, proto, NameToId(cx->names().exec), &has)) return false; if (!has) return false; if (!has) { *result = false; return true; } cx->compartment()->regExps.setOptimizableRegExpPrototypeShape(nproto->lastProperty()); *result = true; return true; } Loading @@ -1671,33 +1699,44 @@ js::RegExpInstanceOptimizable(JSContext* cx, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 2); args.rval().setBoolean(RegExpInstanceOptimizableRaw(cx, &args[0].toObject(), &args[1].toObject())); uint8_t result = false; if (!RegExpInstanceOptimizableRaw(cx, &args[0].toObject(), &args[1].toObject(), &result)) return false; args.rval().setBoolean(result); return true; } bool js::RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* obj, JSObject* proto) js::RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* obj, JSObject* proto, uint8_t* result) { JS::AutoCheckCannotGC nogc; AutoAssertNoPendingException aanpe(cx); RegExpObject* rx = &obj->as<RegExpObject>(); Shape* shape = cx->compartment()->regExps.getOptimizableRegExpInstanceShape(); if (shape == rx->lastProperty()) if (shape == rx->lastProperty()) { *result = true; return true; } if (!rx->hasStaticPrototype()) return false; if (!rx->hasStaticPrototype()) { *result = false; return true; } if (rx->staticPrototype() != proto) return false; if (rx->staticPrototype() != proto) { *result = false; return true; } if (!RegExpObject::isInitialShape(rx)) return false; if (!RegExpObject::isInitialShape(rx)) { *result = false; return true; } cx->compartment()->regExps.setOptimizableRegExpInstanceShape(rx->lastProperty()); *result = true; return true; } Loading js/src/builtin/RegExp.h +2 −2 Original line number Diff line number Diff line Loading @@ -113,13 +113,13 @@ extern MOZ_MUST_USE bool RegExpPrototypeOptimizable(JSContext* cx, unsigned argc, Value* vp); extern MOZ_MUST_USE bool RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto); RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto, uint8_t* result); extern MOZ_MUST_USE bool RegExpInstanceOptimizable(JSContext* cx, unsigned argc, Value* vp); extern MOZ_MUST_USE bool RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* obj, JSObject* proto); RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* obj, JSObject* proto, uint8_t* result); extern MOZ_MUST_USE bool RegExpGetSubstitution(JSContext* cx, HandleLinearString matched, HandleLinearString string, Loading js/src/jit/CodeGenerator.cpp +18 −2 Original line number Diff line number Diff line Loading @@ -2122,15 +2122,23 @@ CodeGenerator::visitOutOfLineRegExpPrototypeOptimizable(OutOfLineRegExpPrototype LRegExpPrototypeOptimizable* ins = ool->ins(); Register object = ToRegister(ins->object()); Register output = ToRegister(ins->output()); Register temp = ToRegister(ins->temp()); saveVolatile(output); masm.reserveStack(sizeof(void*)); masm.moveStackPtrTo(temp); masm.setupUnalignedABICall(output); masm.loadJSContext(output); masm.passABIArg(output); masm.passABIArg(object); masm.passABIArg(temp); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, RegExpPrototypeOptimizableRaw)); masm.storeCallResult(output); masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel()); masm.load8ZeroExtend(Address(masm.getStackPointer(), 0), output); masm.freeStack(sizeof(void*)); restoreVolatile(output); Loading Loading @@ -2184,16 +2192,24 @@ CodeGenerator::visitOutOfLineRegExpInstanceOptimizable(OutOfLineRegExpInstanceOp Register object = ToRegister(ins->object()); Register proto = ToRegister(ins->proto()); Register output = ToRegister(ins->output()); Register temp = ToRegister(ins->temp()); saveVolatile(output); masm.reserveStack(sizeof(void*)); masm.moveStackPtrTo(temp); masm.setupUnalignedABICall(output); masm.loadJSContext(output); masm.passABIArg(output); masm.passABIArg(object); masm.passABIArg(proto); masm.passABIArg(temp); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, RegExpInstanceOptimizableRaw)); masm.storeCallResult(output); masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel()); masm.load8ZeroExtend(Address(masm.getStackPointer(), 0), output); masm.freeStack(sizeof(void*)); restoreVolatile(output); Loading Loading
js/src/builtin/RegExp.cpp +76 −37 Original line number Diff line number Diff line Loading @@ -1579,88 +1579,116 @@ js::RegExpPrototypeOptimizable(JSContext* cx, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 1); args.rval().setBoolean(RegExpPrototypeOptimizableRaw(cx, &args[0].toObject())); uint8_t result = false; if (!RegExpPrototypeOptimizableRaw(cx, &args[0].toObject(), &result)) return false; args.rval().setBoolean(result); return true; } bool js::RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto) js::RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto, uint8_t* result) { JS::AutoCheckCannotGC nogc; AutoAssertNoPendingException aanpe(cx); if (!proto->isNative()) return false; if (!proto->isNative()) { *result = false; return true; } NativeObject* nproto = static_cast<NativeObject*>(proto); Shape* shape = cx->compartment()->regExps.getOptimizableRegExpPrototypeShape(); if (shape == nproto->lastProperty()) if (shape == nproto->lastProperty()) { *result = true; return true; } JSFunction* flagsGetter; if (!GetOwnGetterPure(cx, proto, NameToId(cx->names().flags), &flagsGetter)) return false; if (!flagsGetter) return false; if (!flagsGetter) { *result = false; return true; } if (!IsSelfHostedFunctionWithName(flagsGetter, cx->names().RegExpFlagsGetter)) return false; if (!IsSelfHostedFunctionWithName(flagsGetter, cx->names().RegExpFlagsGetter)) { *result = false; return true; } JSNative globalGetter; if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().global), &globalGetter)) return false; if (globalGetter != regexp_global) return false; if (globalGetter != regexp_global) { *result = false; return true; } JSNative ignoreCaseGetter; if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().ignoreCase), &ignoreCaseGetter)) return false; if (ignoreCaseGetter != regexp_ignoreCase) return false; if (ignoreCaseGetter != regexp_ignoreCase) { *result = false; return true; } JSNative multilineGetter; if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().multiline), &multilineGetter)) return false; if (multilineGetter != regexp_multiline) return false; if (multilineGetter != regexp_multiline) { *result = false; return true; } JSNative stickyGetter; if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().sticky), &stickyGetter)) return false; if (stickyGetter != regexp_sticky) return false; if (stickyGetter != regexp_sticky) { *result = false; return true; } JSNative unicodeGetter; if (!GetOwnNativeGetterPure(cx, proto, NameToId(cx->names().unicode), &unicodeGetter)) return false; if (unicodeGetter != regexp_unicode) return false; if (unicodeGetter != regexp_unicode) { *result = false; return true; } // Check if @@match, @@search, and exec are own data properties, // those values should be tested in selfhosted JS. bool has = false; if (!HasOwnDataPropertyPure(cx, proto, SYMBOL_TO_JSID(cx->wellKnownSymbols().match), &has)) return false; if (!has) return false; if (!has) { *result = false; return true; } if (!HasOwnDataPropertyPure(cx, proto, SYMBOL_TO_JSID(cx->wellKnownSymbols().search), &has)) return false; if (!has) return false; if (!has) { *result = false; return true; } if (!HasOwnDataPropertyPure(cx, proto, NameToId(cx->names().exec), &has)) return false; if (!has) return false; if (!has) { *result = false; return true; } cx->compartment()->regExps.setOptimizableRegExpPrototypeShape(nproto->lastProperty()); *result = true; return true; } Loading @@ -1671,33 +1699,44 @@ js::RegExpInstanceOptimizable(JSContext* cx, unsigned argc, Value* vp) CallArgs args = CallArgsFromVp(argc, vp); MOZ_ASSERT(args.length() == 2); args.rval().setBoolean(RegExpInstanceOptimizableRaw(cx, &args[0].toObject(), &args[1].toObject())); uint8_t result = false; if (!RegExpInstanceOptimizableRaw(cx, &args[0].toObject(), &args[1].toObject(), &result)) return false; args.rval().setBoolean(result); return true; } bool js::RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* obj, JSObject* proto) js::RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* obj, JSObject* proto, uint8_t* result) { JS::AutoCheckCannotGC nogc; AutoAssertNoPendingException aanpe(cx); RegExpObject* rx = &obj->as<RegExpObject>(); Shape* shape = cx->compartment()->regExps.getOptimizableRegExpInstanceShape(); if (shape == rx->lastProperty()) if (shape == rx->lastProperty()) { *result = true; return true; } if (!rx->hasStaticPrototype()) return false; if (!rx->hasStaticPrototype()) { *result = false; return true; } if (rx->staticPrototype() != proto) return false; if (rx->staticPrototype() != proto) { *result = false; return true; } if (!RegExpObject::isInitialShape(rx)) return false; if (!RegExpObject::isInitialShape(rx)) { *result = false; return true; } cx->compartment()->regExps.setOptimizableRegExpInstanceShape(rx->lastProperty()); *result = true; return true; } Loading
js/src/builtin/RegExp.h +2 −2 Original line number Diff line number Diff line Loading @@ -113,13 +113,13 @@ extern MOZ_MUST_USE bool RegExpPrototypeOptimizable(JSContext* cx, unsigned argc, Value* vp); extern MOZ_MUST_USE bool RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto); RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto, uint8_t* result); extern MOZ_MUST_USE bool RegExpInstanceOptimizable(JSContext* cx, unsigned argc, Value* vp); extern MOZ_MUST_USE bool RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* obj, JSObject* proto); RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* obj, JSObject* proto, uint8_t* result); extern MOZ_MUST_USE bool RegExpGetSubstitution(JSContext* cx, HandleLinearString matched, HandleLinearString string, Loading
js/src/jit/CodeGenerator.cpp +18 −2 Original line number Diff line number Diff line Loading @@ -2122,15 +2122,23 @@ CodeGenerator::visitOutOfLineRegExpPrototypeOptimizable(OutOfLineRegExpPrototype LRegExpPrototypeOptimizable* ins = ool->ins(); Register object = ToRegister(ins->object()); Register output = ToRegister(ins->output()); Register temp = ToRegister(ins->temp()); saveVolatile(output); masm.reserveStack(sizeof(void*)); masm.moveStackPtrTo(temp); masm.setupUnalignedABICall(output); masm.loadJSContext(output); masm.passABIArg(output); masm.passABIArg(object); masm.passABIArg(temp); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, RegExpPrototypeOptimizableRaw)); masm.storeCallResult(output); masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel()); masm.load8ZeroExtend(Address(masm.getStackPointer(), 0), output); masm.freeStack(sizeof(void*)); restoreVolatile(output); Loading Loading @@ -2184,16 +2192,24 @@ CodeGenerator::visitOutOfLineRegExpInstanceOptimizable(OutOfLineRegExpInstanceOp Register object = ToRegister(ins->object()); Register proto = ToRegister(ins->proto()); Register output = ToRegister(ins->output()); Register temp = ToRegister(ins->temp()); saveVolatile(output); masm.reserveStack(sizeof(void*)); masm.moveStackPtrTo(temp); masm.setupUnalignedABICall(output); masm.loadJSContext(output); masm.passABIArg(output); masm.passABIArg(object); masm.passABIArg(proto); masm.passABIArg(temp); masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, RegExpInstanceOptimizableRaw)); masm.storeCallResult(output); masm.branchIfFalseBool(ReturnReg, masm.exceptionLabel()); masm.load8ZeroExtend(Address(masm.getStackPointer(), 0), output); masm.freeStack(sizeof(void*)); restoreVolatile(output); Loading