From a5f725d4f65a4825b59636206d76f05ebe310334 Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Thu, 20 Jul 2017 18:47:28 +0200 Subject: [PATCH] Bug 1382612 - Support default class constructors in Ion. r=tcampbell --- js/src/jit/CodeGenerator.cpp | 15 +++++++++++++++ js/src/jit/CodeGenerator.h | 1 + js/src/jit/IonBuilder.cpp | 13 ++++++++++++- js/src/jit/IonBuilder.h | 1 + js/src/jit/Lowering.cpp | 8 ++++++++ js/src/jit/Lowering.h | 1 + js/src/jit/MIR.h | 23 +++++++++++++++++++++++ js/src/jit/MOpcodes.h | 1 + js/src/jit/shared/LIR-shared.h | 10 ++++++++++ js/src/jit/shared/LOpcodes-shared.h | 1 + 10 files changed, 73 insertions(+), 1 deletion(-) diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index 0b778bfa45e4..430e18b6d906 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -2584,6 +2584,21 @@ CodeGenerator::visitNullarySharedStub(LNullarySharedStub* lir) } } +typedef JSFunction* (*MakeDefaultConstructorFn)(JSContext*, HandleScript, + jsbytecode*, HandleObject); +static const VMFunction MakeDefaultConstructorInfo = + FunctionInfo(js::MakeDefaultConstructor, + "MakeDefaultConstructor"); + +void +CodeGenerator::visitClassConstructor(LClassConstructor* lir) +{ + pushArg(ImmPtr(nullptr)); + pushArg(ImmPtr(lir->mir()->pc())); + pushArg(ImmGCPtr(current->mir()->info().script())); + callVM(MakeDefaultConstructorInfo, lir); +} + typedef JSObject* (*LambdaFn)(JSContext*, HandleFunction, HandleObject); static const VMFunction LambdaInfo = FunctionInfo(js::Lambda, "Lambda"); diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index 5882a623469e..ed94e405b284 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -137,6 +137,7 @@ class CodeGenerator final : public CodeGeneratorSpecific void visitBinarySharedStub(LBinarySharedStub* lir); void visitUnarySharedStub(LUnarySharedStub* lir); void visitNullarySharedStub(LNullarySharedStub* lir); + void visitClassConstructor(LClassConstructor* lir); void visitLambda(LLambda* lir); void visitOutOfLineLambdaArrow(OutOfLineLambdaArrow* ool); void visitLambdaArrow(LLambdaArrow* lir); diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index d9ee12a31470..dfce3601ebd6 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -2226,6 +2226,9 @@ IonBuilder::inspectOpcode(JSOp op) case JSOP_OBJECT: return jsop_object(info().getObject(pc)); + case JSOP_CLASSCONSTRUCTOR: + return jsop_classconstructor(); + case JSOP_TYPEOF: case JSOP_TYPEOFEXPR: return jsop_typeof(); @@ -2360,7 +2363,6 @@ IonBuilder::inspectOpcode(JSOp op) case JSOP_OBJWITHPROTO: case JSOP_BUILTINPROTO: case JSOP_INITHOMEOBJECT: - case JSOP_CLASSCONSTRUCTOR: case JSOP_DERIVEDCONSTRUCTOR: case JSOP_CHECKTHIS: case JSOP_CHECKRETURN: @@ -12161,6 +12163,15 @@ IonBuilder::jsop_object(JSObject* obj) return Ok(); } +AbortReasonOr +IonBuilder::jsop_classconstructor() +{ + MClassConstructor* constructor = MClassConstructor::New(alloc(), pc); + current->add(constructor); + current->push(constructor); + return resumeAfter(constructor); +} + AbortReasonOr IonBuilder::jsop_lambda(JSFunction* fun) { diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 5f92cc014f77..2122c7341a6e 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -563,6 +563,7 @@ class IonBuilder AbortReasonOr jsop_initprop_getter_setter(PropertyName* name); AbortReasonOr jsop_regexp(RegExpObject* reobj); AbortReasonOr jsop_object(JSObject* obj); + AbortReasonOr jsop_classconstructor(); AbortReasonOr jsop_lambda(JSFunction* fun); AbortReasonOr jsop_lambda_arrow(JSFunction* fun); AbortReasonOr jsop_setfunname(uint8_t prefixKind); diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 9519ed796ee7..f48ed30881eb 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -2505,6 +2505,14 @@ LIRGenerator::visitNullarySharedStub(MNullarySharedStub* ins) assignSafepoint(lir, ins); } +void +LIRGenerator::visitClassConstructor(MClassConstructor* ins) +{ + LClassConstructor* lir = new(alloc()) LClassConstructor(); + defineReturn(lir, ins); + assignSafepoint(lir, ins); +} + void LIRGenerator::visitLambda(MLambda* ins) { diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index 0ae68b71c4d1..6f052fd1509f 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -185,6 +185,7 @@ class LIRGenerator : public LIRGeneratorSpecific void visitBinarySharedStub(MBinarySharedStub* ins); void visitUnarySharedStub(MUnarySharedStub* ins); void visitNullarySharedStub(MNullarySharedStub* ins); + void visitClassConstructor(MClassConstructor* ins); void visitLambda(MLambda* ins); void visitLambdaArrow(MLambdaArrow* ins); void visitSetFunName(MSetFunName* ins); diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 3538421f262c..d5beb10bd5b9 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -8486,6 +8486,29 @@ class MSubstr } }; +class MClassConstructor : public MNullaryInstruction +{ + jsbytecode* pc_; + + explicit MClassConstructor(jsbytecode* pc) + : pc_(pc) + { + setResultType(MIRType::Object); + } + + public: + INSTRUCTION_HEADER(ClassConstructor) + TRIVIAL_NEW_WRAPPERS + + jsbytecode* pc() const { + return pc_; + } + + AliasSet getAliasSet() const override { + return AliasSet::None(); + } +}; + struct LambdaFunctionInfo { // The functions used in lambdas are the canonical original function in diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index 75eeb7a7d281..74ee04e02eff 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -161,6 +161,7 @@ namespace jit { _(RegExpInstanceOptimizable) \ _(GetFirstDollarIndex) \ _(StringReplace) \ + _(ClassConstructor) \ _(Lambda) \ _(LambdaArrow) \ _(SetFunName) \ diff --git a/js/src/jit/shared/LIR-shared.h b/js/src/jit/shared/LIR-shared.h index 727fb1e5b728..36c52708de65 100644 --- a/js/src/jit/shared/LIR-shared.h +++ b/js/src/jit/shared/LIR-shared.h @@ -4987,6 +4987,16 @@ class LNullarySharedStub : public LCallInstructionHelper } }; +class LClassConstructor : public LCallInstructionHelper<1, 0, 0> +{ + public: + LIR_HEADER(ClassConstructor) + + const MClassConstructor* mir() const { + return mir_->toClassConstructor(); + } +}; + class LLambdaForSingleton : public LCallInstructionHelper<1, 1, 0> { public: diff --git a/js/src/jit/shared/LOpcodes-shared.h b/js/src/jit/shared/LOpcodes-shared.h index 21cdabb1ddc8..9457be68f502 100644 --- a/js/src/jit/shared/LOpcodes-shared.h +++ b/js/src/jit/shared/LOpcodes-shared.h @@ -239,6 +239,7 @@ _(BinarySharedStub) \ _(UnarySharedStub) \ _(NullarySharedStub) \ + _(ClassConstructor) \ _(Lambda) \ _(LambdaArrow) \ _(LambdaForSingleton) \