mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-26 11:45:37 +00:00
Bug 887016 - Part 7: Add RegExpInstanceOptimizable. r=nbp
This commit is contained in:
parent
e866ceb7f2
commit
1b4d64f711
@ -1104,3 +1104,55 @@ js::RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto, uint8_t* resul
|
|||||||
*result = true;
|
*result = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
js::RegExpInstanceOptimizable(JSContext* cx, unsigned argc, Value* vp)
|
||||||
|
{
|
||||||
|
// This can only be called from self-hosted code.
|
||||||
|
CallArgs args = CallArgsFromVp(argc, vp);
|
||||||
|
MOZ_ASSERT(args.length() == 2);
|
||||||
|
|
||||||
|
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* rx, JSObject* proto, uint8_t* result)
|
||||||
|
{
|
||||||
|
JS::AutoCheckCannotGC nogc;
|
||||||
|
if (!rx->isNative()) {
|
||||||
|
*result = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeObject* nobj = static_cast<NativeObject*>(rx);
|
||||||
|
|
||||||
|
Shape* shape = cx->compartment()->regExps.getOptimizableRegExpInstanceShape();
|
||||||
|
if (shape == nobj->lastProperty()) {
|
||||||
|
*result = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rx->hasLazyPrototype()) {
|
||||||
|
*result = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rx->getTaggedProto().toObjectOrNull() != proto) {
|
||||||
|
*result = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!RegExpObject::isInitialShape(nobj)) {
|
||||||
|
*result = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cx->compartment()->regExps.setOptimizableRegExpInstanceShape(nobj->lastProperty());
|
||||||
|
*result = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -97,6 +97,12 @@ RegExpPrototypeOptimizable(JSContext* cx, unsigned argc, Value* vp);
|
|||||||
extern bool
|
extern bool
|
||||||
RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto, uint8_t* result);
|
RegExpPrototypeOptimizableRaw(JSContext* cx, JSObject* proto, uint8_t* result);
|
||||||
|
|
||||||
|
extern bool
|
||||||
|
RegExpInstanceOptimizable(JSContext* cx, unsigned argc, Value* vp);
|
||||||
|
|
||||||
|
extern bool
|
||||||
|
RegExpInstanceOptimizableRaw(JSContext* cx, JSObject* rx, JSObject* proto, uint8_t* result);
|
||||||
|
|
||||||
// RegExp ClassSpec members used in RegExpObject.cpp.
|
// RegExp ClassSpec members used in RegExpObject.cpp.
|
||||||
extern bool
|
extern bool
|
||||||
regexp_construct(JSContext* cx, unsigned argc, Value* vp);
|
regexp_construct(JSContext* cx, unsigned argc, Value* vp);
|
||||||
|
@ -2035,6 +2035,77 @@ CodeGenerator::visitOutOfLineRegExpPrototypeOptimizable(OutOfLineRegExpPrototype
|
|||||||
masm.jump(ool->rejoin());
|
masm.jump(ool->rejoin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class OutOfLineRegExpInstanceOptimizable : public OutOfLineCodeBase<CodeGenerator>
|
||||||
|
{
|
||||||
|
LRegExpInstanceOptimizable* ins_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit OutOfLineRegExpInstanceOptimizable(LRegExpInstanceOptimizable* ins)
|
||||||
|
: ins_(ins)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void accept(CodeGenerator* codegen) {
|
||||||
|
codegen->visitOutOfLineRegExpInstanceOptimizable(this);
|
||||||
|
}
|
||||||
|
LRegExpInstanceOptimizable* ins() const {
|
||||||
|
return ins_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeGenerator::visitRegExpInstanceOptimizable(LRegExpInstanceOptimizable* ins)
|
||||||
|
{
|
||||||
|
Register object = ToRegister(ins->object());
|
||||||
|
Register output = ToRegister(ins->output());
|
||||||
|
Register temp = ToRegister(ins->temp());
|
||||||
|
|
||||||
|
OutOfLineRegExpInstanceOptimizable* ool = new(alloc()) OutOfLineRegExpInstanceOptimizable(ins);
|
||||||
|
addOutOfLineCode(ool, ins->mir());
|
||||||
|
|
||||||
|
masm.loadJSContext(temp);
|
||||||
|
masm.loadPtr(Address(temp, JSContext::offsetOfCompartment()), temp);
|
||||||
|
masm.loadPtr(Address(temp, JSCompartment::offsetOfRegExps()), temp);
|
||||||
|
masm.loadPtr(Address(temp, RegExpCompartment::offsetOfOptimizableRegExpInstanceShape()),
|
||||||
|
temp);
|
||||||
|
|
||||||
|
masm.loadPtr(Address(object, JSObject::offsetOfShape()), output);
|
||||||
|
masm.branchPtr(Assembler::NotEqual, output, temp, ool->entry());
|
||||||
|
masm.move32(Imm32(0x1), output);
|
||||||
|
|
||||||
|
masm.bind(ool->rejoin());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CodeGenerator::visitOutOfLineRegExpInstanceOptimizable(OutOfLineRegExpInstanceOptimizable* ool)
|
||||||
|
{
|
||||||
|
LRegExpInstanceOptimizable* ins = ool->ins();
|
||||||
|
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.branchIfFalseBool(ReturnReg, masm.exceptionLabel());
|
||||||
|
|
||||||
|
masm.load8ZeroExtend(Address(masm.getStackPointer(), 0), output);
|
||||||
|
masm.freeStack(sizeof(void*));
|
||||||
|
|
||||||
|
restoreVolatile(output);
|
||||||
|
|
||||||
|
masm.jump(ool->rejoin());
|
||||||
|
}
|
||||||
|
|
||||||
typedef JSString* (*RegExpReplaceFn)(JSContext*, HandleString, HandleObject, HandleString);
|
typedef JSString* (*RegExpReplaceFn)(JSContext*, HandleString, HandleObject, HandleString);
|
||||||
static const VMFunction RegExpReplaceInfo = FunctionInfo<RegExpReplaceFn>(RegExpReplace);
|
static const VMFunction RegExpReplaceInfo = FunctionInfo<RegExpReplaceFn>(RegExpReplace);
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ class OutOfLineIsConstructor;
|
|||||||
class OutOfLineRegExpMatcher;
|
class OutOfLineRegExpMatcher;
|
||||||
class OutOfLineRegExpTester;
|
class OutOfLineRegExpTester;
|
||||||
class OutOfLineRegExpPrototypeOptimizable;
|
class OutOfLineRegExpPrototypeOptimizable;
|
||||||
|
class OutOfLineRegExpInstanceOptimizable;
|
||||||
class OutOfLineLambdaArrow;
|
class OutOfLineLambdaArrow;
|
||||||
|
|
||||||
class CodeGenerator : public CodeGeneratorSpecific
|
class CodeGenerator : public CodeGeneratorSpecific
|
||||||
@ -116,6 +117,8 @@ class CodeGenerator : public CodeGeneratorSpecific
|
|||||||
void visitOutOfLineRegExpTester(OutOfLineRegExpTester* ool);
|
void visitOutOfLineRegExpTester(OutOfLineRegExpTester* ool);
|
||||||
void visitRegExpPrototypeOptimizable(LRegExpPrototypeOptimizable* lir);
|
void visitRegExpPrototypeOptimizable(LRegExpPrototypeOptimizable* lir);
|
||||||
void visitOutOfLineRegExpPrototypeOptimizable(OutOfLineRegExpPrototypeOptimizable* ool);
|
void visitOutOfLineRegExpPrototypeOptimizable(OutOfLineRegExpPrototypeOptimizable* ool);
|
||||||
|
void visitRegExpInstanceOptimizable(LRegExpInstanceOptimizable* lir);
|
||||||
|
void visitOutOfLineRegExpInstanceOptimizable(OutOfLineRegExpInstanceOptimizable* ool);
|
||||||
void visitRegExpReplace(LRegExpReplace* lir);
|
void visitRegExpReplace(LRegExpReplace* lir);
|
||||||
void visitStringReplace(LStringReplace* lir);
|
void visitStringReplace(LStringReplace* lir);
|
||||||
void emitSharedStub(ICStub::Kind kind, LInstruction* lir);
|
void emitSharedStub(ICStub::Kind kind, LInstruction* lir);
|
||||||
|
@ -69,6 +69,7 @@
|
|||||||
_(RegExpTester) \
|
_(RegExpTester) \
|
||||||
_(IsRegExpObject) \
|
_(IsRegExpObject) \
|
||||||
_(RegExpPrototypeOptimizable) \
|
_(RegExpPrototypeOptimizable) \
|
||||||
|
_(RegExpInstanceOptimizable) \
|
||||||
\
|
\
|
||||||
_(String) \
|
_(String) \
|
||||||
_(StringSplit) \
|
_(StringSplit) \
|
||||||
|
@ -824,6 +824,7 @@ class IonBuilder
|
|||||||
InliningStatus inlineRegExpTester(CallInfo& callInfo);
|
InliningStatus inlineRegExpTester(CallInfo& callInfo);
|
||||||
InliningStatus inlineIsRegExpObject(CallInfo& callInfo);
|
InliningStatus inlineIsRegExpObject(CallInfo& callInfo);
|
||||||
InliningStatus inlineRegExpPrototypeOptimizable(CallInfo& callInfo);
|
InliningStatus inlineRegExpPrototypeOptimizable(CallInfo& callInfo);
|
||||||
|
InliningStatus inlineRegExpInstanceOptimizable(CallInfo& callInfo);
|
||||||
|
|
||||||
// Object natives and intrinsics.
|
// Object natives and intrinsics.
|
||||||
InliningStatus inlineObjectCreate(CallInfo& callInfo);
|
InliningStatus inlineObjectCreate(CallInfo& callInfo);
|
||||||
|
@ -2295,6 +2295,18 @@ LIRGenerator::visitRegExpPrototypeOptimizable(MRegExpPrototypeOptimizable* ins)
|
|||||||
define(lir, ins);
|
define(lir, ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LIRGenerator::visitRegExpInstanceOptimizable(MRegExpInstanceOptimizable* ins)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(ins->object()->type() == MIRType_Object);
|
||||||
|
MOZ_ASSERT(ins->proto()->type() == MIRType_Object);
|
||||||
|
MOZ_ASSERT(ins->type() == MIRType_Boolean);
|
||||||
|
LRegExpInstanceOptimizable* lir = new(alloc()) LRegExpInstanceOptimizable(useRegister(ins->object()),
|
||||||
|
useRegister(ins->proto()),
|
||||||
|
temp());
|
||||||
|
define(lir, ins);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LIRGenerator::visitRegExpReplace(MRegExpReplace* ins)
|
LIRGenerator::visitRegExpReplace(MRegExpReplace* ins)
|
||||||
{
|
{
|
||||||
|
@ -166,6 +166,7 @@ class LIRGenerator : public LIRGeneratorSpecific
|
|||||||
void visitRegExpMatcher(MRegExpMatcher* ins);
|
void visitRegExpMatcher(MRegExpMatcher* ins);
|
||||||
void visitRegExpTester(MRegExpTester* ins);
|
void visitRegExpTester(MRegExpTester* ins);
|
||||||
void visitRegExpPrototypeOptimizable(MRegExpPrototypeOptimizable* ins);
|
void visitRegExpPrototypeOptimizable(MRegExpPrototypeOptimizable* ins);
|
||||||
|
void visitRegExpInstanceOptimizable(MRegExpInstanceOptimizable* ins);
|
||||||
void visitRegExpReplace(MRegExpReplace* ins);
|
void visitRegExpReplace(MRegExpReplace* ins);
|
||||||
void visitStringReplace(MStringReplace* ins);
|
void visitStringReplace(MStringReplace* ins);
|
||||||
void visitBinarySharedStub(MBinarySharedStub* ins);
|
void visitBinarySharedStub(MBinarySharedStub* ins);
|
||||||
|
@ -184,6 +184,8 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
|
|||||||
return inlineIsRegExpObject(callInfo);
|
return inlineIsRegExpObject(callInfo);
|
||||||
case InlinableNative::RegExpPrototypeOptimizable:
|
case InlinableNative::RegExpPrototypeOptimizable:
|
||||||
return inlineRegExpPrototypeOptimizable(callInfo);
|
return inlineRegExpPrototypeOptimizable(callInfo);
|
||||||
|
case InlinableNative::RegExpInstanceOptimizable:
|
||||||
|
return inlineRegExpInstanceOptimizable(callInfo);
|
||||||
|
|
||||||
// String natives.
|
// String natives.
|
||||||
case InlinableNative::String:
|
case InlinableNative::String:
|
||||||
@ -1909,6 +1911,35 @@ IonBuilder::inlineRegExpPrototypeOptimizable(CallInfo& callInfo)
|
|||||||
return InliningStatus_Inlined;
|
return InliningStatus_Inlined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IonBuilder::InliningStatus
|
||||||
|
IonBuilder::inlineRegExpInstanceOptimizable(CallInfo& callInfo)
|
||||||
|
{
|
||||||
|
if (callInfo.argc() != 2 || callInfo.constructing()) {
|
||||||
|
trackOptimizationOutcome(TrackedOutcome::CantInlineNativeBadForm);
|
||||||
|
return InliningStatus_NotInlined;
|
||||||
|
}
|
||||||
|
|
||||||
|
MDefinition* rxArg = callInfo.getArg(0);
|
||||||
|
MDefinition* protoArg = callInfo.getArg(1);
|
||||||
|
|
||||||
|
if (rxArg->type() != MIRType_Object)
|
||||||
|
return InliningStatus_NotInlined;
|
||||||
|
|
||||||
|
if (protoArg->type() != MIRType_Object)
|
||||||
|
return InliningStatus_NotInlined;
|
||||||
|
|
||||||
|
if (getInlineReturnType() != MIRType_Boolean)
|
||||||
|
return InliningStatus_NotInlined;
|
||||||
|
|
||||||
|
callInfo.setImplicitlyUsedUnchecked();
|
||||||
|
|
||||||
|
MInstruction* opt = MRegExpInstanceOptimizable::New(alloc(), rxArg, protoArg);
|
||||||
|
current->add(opt);
|
||||||
|
current->push(opt);
|
||||||
|
|
||||||
|
return InliningStatus_Inlined;
|
||||||
|
}
|
||||||
|
|
||||||
IonBuilder::InliningStatus
|
IonBuilder::InliningStatus
|
||||||
IonBuilder::inlineStrReplace(CallInfo& callInfo)
|
IonBuilder::inlineStrReplace(CallInfo& callInfo)
|
||||||
{
|
{
|
||||||
|
@ -8017,6 +8017,35 @@ class MRegExpPrototypeOptimizable
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MRegExpInstanceOptimizable
|
||||||
|
: public MBinaryInstruction,
|
||||||
|
public MixPolicy<ObjectPolicy<0>, ObjectPolicy<1> >::Data
|
||||||
|
{
|
||||||
|
explicit MRegExpInstanceOptimizable(MDefinition* object, MDefinition* proto)
|
||||||
|
: MBinaryInstruction(object, proto)
|
||||||
|
{
|
||||||
|
setResultType(MIRType_Boolean);
|
||||||
|
setMovable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
INSTRUCTION_HEADER(RegExpInstanceOptimizable)
|
||||||
|
|
||||||
|
static MRegExpInstanceOptimizable* New(TempAllocator& alloc, MDefinition* obj,
|
||||||
|
MDefinition* proto) {
|
||||||
|
return new(alloc) MRegExpInstanceOptimizable(obj, proto);
|
||||||
|
}
|
||||||
|
MDefinition* object() const {
|
||||||
|
return getOperand(0);
|
||||||
|
}
|
||||||
|
MDefinition* proto() const {
|
||||||
|
return getOperand(1);
|
||||||
|
}
|
||||||
|
AliasSet getAliasSet() const override {
|
||||||
|
return AliasSet::None();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <class Policy1>
|
template <class Policy1>
|
||||||
class MStrReplace
|
class MStrReplace
|
||||||
: public MTernaryInstruction,
|
: public MTernaryInstruction,
|
||||||
|
@ -148,6 +148,7 @@ namespace jit {
|
|||||||
_(RegExpMatcher) \
|
_(RegExpMatcher) \
|
||||||
_(RegExpTester) \
|
_(RegExpTester) \
|
||||||
_(RegExpPrototypeOptimizable) \
|
_(RegExpPrototypeOptimizable) \
|
||||||
|
_(RegExpInstanceOptimizable) \
|
||||||
_(RegExpReplace) \
|
_(RegExpReplace) \
|
||||||
_(StringReplace) \
|
_(StringReplace) \
|
||||||
_(Lambda) \
|
_(Lambda) \
|
||||||
|
@ -4353,6 +4353,31 @@ class LRegExpPrototypeOptimizable : public LInstructionHelper<1, 1, 1>
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LRegExpInstanceOptimizable : public LInstructionHelper<1, 2, 1>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LIR_HEADER(RegExpInstanceOptimizable);
|
||||||
|
explicit LRegExpInstanceOptimizable(const LAllocation& object, const LAllocation& proto,
|
||||||
|
const LDefinition& temp) {
|
||||||
|
setOperand(0, object);
|
||||||
|
setOperand(1, proto);
|
||||||
|
setTemp(0, temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
const LAllocation* object() {
|
||||||
|
return getOperand(0);
|
||||||
|
}
|
||||||
|
const LAllocation* proto() {
|
||||||
|
return getOperand(1);
|
||||||
|
}
|
||||||
|
const LDefinition* temp() {
|
||||||
|
return getTemp(0);
|
||||||
|
}
|
||||||
|
MRegExpInstanceOptimizable* mir() const {
|
||||||
|
return mir_->toRegExpInstanceOptimizable();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class LStrReplace : public LCallInstructionHelper<1, 3, 0>
|
class LStrReplace : public LCallInstructionHelper<1, 3, 0>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -209,6 +209,7 @@
|
|||||||
_(RegExpMatcher) \
|
_(RegExpMatcher) \
|
||||||
_(RegExpTester) \
|
_(RegExpTester) \
|
||||||
_(RegExpPrototypeOptimizable) \
|
_(RegExpPrototypeOptimizable) \
|
||||||
|
_(RegExpInstanceOptimizable) \
|
||||||
_(RegExpReplace) \
|
_(RegExpReplace) \
|
||||||
_(StringReplace) \
|
_(StringReplace) \
|
||||||
_(Substr) \
|
_(Substr) \
|
||||||
|
@ -721,7 +721,8 @@ RegExpShared::sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf)
|
|||||||
RegExpCompartment::RegExpCompartment(JSRuntime* rt)
|
RegExpCompartment::RegExpCompartment(JSRuntime* rt)
|
||||||
: set_(rt),
|
: set_(rt),
|
||||||
matchResultTemplateObject_(nullptr),
|
matchResultTemplateObject_(nullptr),
|
||||||
optimizableRegExpPrototypeShape_(nullptr)
|
optimizableRegExpPrototypeShape_(nullptr),
|
||||||
|
optimizableRegExpInstanceShape_(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
RegExpCompartment::~RegExpCompartment()
|
RegExpCompartment::~RegExpCompartment()
|
||||||
@ -852,6 +853,12 @@ RegExpCompartment::sweep(JSRuntime* rt)
|
|||||||
{
|
{
|
||||||
optimizableRegExpPrototypeShape_.set(nullptr);
|
optimizableRegExpPrototypeShape_.set(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (optimizableRegExpInstanceShape_ &&
|
||||||
|
IsAboutToBeFinalized(&optimizableRegExpInstanceShape_))
|
||||||
|
{
|
||||||
|
optimizableRegExpInstanceShape_.set(nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -336,6 +336,13 @@ class RegExpCompartment
|
|||||||
*/
|
*/
|
||||||
ReadBarriered<Shape*> optimizableRegExpPrototypeShape_;
|
ReadBarriered<Shape*> optimizableRegExpPrototypeShape_;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The shape of RegExp instance that satisfies following:
|
||||||
|
* * lastProperty is lastIndex
|
||||||
|
* * prototype is RegExp.prototype
|
||||||
|
*/
|
||||||
|
ReadBarriered<Shape*> optimizableRegExpInstanceShape_;
|
||||||
|
|
||||||
ArrayObject* createMatchResultTemplateObject(JSContext* cx);
|
ArrayObject* createMatchResultTemplateObject(JSContext* cx);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -365,10 +372,19 @@ class RegExpCompartment
|
|||||||
void setOptimizableRegExpPrototypeShape(Shape* shape) {
|
void setOptimizableRegExpPrototypeShape(Shape* shape) {
|
||||||
optimizableRegExpPrototypeShape_ = shape;
|
optimizableRegExpPrototypeShape_ = shape;
|
||||||
}
|
}
|
||||||
|
Shape* getOptimizableRegExpInstanceShape() {
|
||||||
|
return optimizableRegExpInstanceShape_;
|
||||||
|
}
|
||||||
|
void setOptimizableRegExpInstanceShape(Shape* shape) {
|
||||||
|
optimizableRegExpInstanceShape_ = shape;
|
||||||
|
}
|
||||||
|
|
||||||
static size_t offsetOfOptimizableRegExpPrototypeShape() {
|
static size_t offsetOfOptimizableRegExpPrototypeShape() {
|
||||||
return offsetof(RegExpCompartment, optimizableRegExpPrototypeShape_);
|
return offsetof(RegExpCompartment, optimizableRegExpPrototypeShape_);
|
||||||
}
|
}
|
||||||
|
static size_t offsetOfOptimizableRegExpInstanceShape() {
|
||||||
|
return offsetof(RegExpCompartment, optimizableRegExpInstanceShape_);
|
||||||
|
}
|
||||||
|
|
||||||
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
|
size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf);
|
||||||
};
|
};
|
||||||
@ -409,6 +425,15 @@ class RegExpObject : public NativeObject
|
|||||||
|
|
||||||
static unsigned lastIndexSlot() { return LAST_INDEX_SLOT; }
|
static unsigned lastIndexSlot() { return LAST_INDEX_SLOT; }
|
||||||
|
|
||||||
|
static bool isInitialShape(NativeObject* nobj) {
|
||||||
|
Shape* shape = nobj->lastProperty();
|
||||||
|
if (!shape->hasSlot())
|
||||||
|
return false;
|
||||||
|
if (shape->maybeSlot() != LAST_INDEX_SLOT)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const Value& getLastIndex() const { return getSlot(LAST_INDEX_SLOT); }
|
const Value& getLastIndex() const { return getSlot(LAST_INDEX_SLOT); }
|
||||||
|
|
||||||
void setLastIndex(double d) {
|
void setLastIndex(double d) {
|
||||||
|
@ -2373,6 +2373,8 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
|||||||
JS_FN("RegExpCreate", intrinsic_RegExpCreate, 2,0),
|
JS_FN("RegExpCreate", intrinsic_RegExpCreate, 2,0),
|
||||||
JS_INLINABLE_FN("RegExpPrototypeOptimizable", RegExpPrototypeOptimizable, 1,0,
|
JS_INLINABLE_FN("RegExpPrototypeOptimizable", RegExpPrototypeOptimizable, 1,0,
|
||||||
RegExpPrototypeOptimizable),
|
RegExpPrototypeOptimizable),
|
||||||
|
JS_INLINABLE_FN("RegExpInstanceOptimizable", RegExpInstanceOptimizable, 1,0,
|
||||||
|
RegExpInstanceOptimizable),
|
||||||
|
|
||||||
// See builtin/RegExp.h for descriptions of the regexp_* functions.
|
// See builtin/RegExp.h for descriptions of the regexp_* functions.
|
||||||
JS_FN("regexp_exec_no_statics", regexp_exec_no_statics, 2,0),
|
JS_FN("regexp_exec_no_statics", regexp_exec_no_statics, 2,0),
|
||||||
|
Loading…
Reference in New Issue
Block a user