From f3d1453f83709977d2248ab0b6fc1fe0d1a590d3 Mon Sep 17 00:00:00 2001 From: "whesse@chromium.org" Date: Mon, 4 Jul 2011 14:13:08 +0000 Subject: [PATCH] As part of allowing different contexts for inlined functions, eliminate most explicit reads of the context from the stack frame in ia32 crankshaft codegen. Eliminates the enum flag RESTORE_CONTEXT and CONTEXT_ADJUSTED, and adds a context HValue and LOperand to many hydrogen and lithium instructions. Context is still used from the stack from in CallKnownFunction (this seems safe), and in CallRuntimeFromDeferred in lithium-codegen-ia32.cc, which needs to be fixed. BUG= TEST= Review URL: http://codereview.chromium.org/7132002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8529 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/lithium-arm.cc | 10 +- src/hydrogen-instructions.cc | 8 +- src/hydrogen-instructions.h | 368 ++++++++++++++++++++++++--------------- src/hydrogen.cc | 127 +++++++++----- src/hydrogen.h | 3 +- src/ia32/lithium-codegen-ia32.cc | 190 +++++++++++--------- src/ia32/lithium-codegen-ia32.h | 20 +-- src/ia32/lithium-ia32.cc | 86 ++++++--- src/ia32/lithium-ia32.h | 184 +++++++++++++------- src/x64/lithium-x64.cc | 10 +- 10 files changed, 617 insertions(+), 389 deletions(-) diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 63e3169..22e7e41 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -836,11 +836,11 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op, } ASSERT(instr->representation().IsInteger32()); - ASSERT(instr->OperandAt(0)->representation().IsInteger32()); - ASSERT(instr->OperandAt(1)->representation().IsInteger32()); - LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); + ASSERT(instr->left()->representation().IsInteger32()); + ASSERT(instr->right()->representation().IsInteger32()); + LOperand* left = UseRegisterAtStart(instr->left()); - HValue* right_value = instr->OperandAt(1); + HValue* right_value = instr->right(); LOperand* right = NULL; int constant_value = 0; if (right_value->IsConstant()) { @@ -1064,7 +1064,7 @@ LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( HInstanceOfKnownGlobal* instr) { LInstanceOfKnownGlobal* result = - new LInstanceOfKnownGlobal(UseFixed(instr->value(), r0), FixedTemp(r4)); + new LInstanceOfKnownGlobal(UseFixed(instr->left(), r0), FixedTemp(r4)); return MarkAsCall(DefineFixed(result, r0), instr); } diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index c8db9a0..e28b9ef 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -1268,13 +1268,15 @@ void HLoadNamedField::PrintDataTo(StringStream* stream) { } -HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* object, +HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context, + HValue* object, ZoneMapList* types, Handle name) - : HUnaryOperation(object), - types_(Min(types->length(), kMaxLoadPolymorphism)), + : types_(Min(types->length(), kMaxLoadPolymorphism)), name_(name), need_generic_(false) { + SetOperandAt(0, context); + SetOperandAt(1, object); set_representation(Representation::Tagged()); SetFlag(kDependsOnMaps); for (int i = 0; diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 8ee8419..9b44ad9 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -1021,9 +1021,11 @@ class HUnaryOperation: public HTemplateInstruction<1> { }; -class HThrow: public HUnaryOperation { +class HThrow: public HTemplateInstruction<2> { public: - explicit HThrow(HValue* value) : HUnaryOperation(value) { + HThrow(HValue* context, HValue* value) { + SetOperandAt(0, context); + SetOperandAt(1, value); SetAllSideEffects(); } @@ -1031,6 +1033,9 @@ class HThrow: public HUnaryOperation { return Representation::Tagged(); } + HValue* context() { return OperandAt(0); } + HValue* value() { return OperandAt(1); } + DECLARE_CONCRETE_INSTRUCTION(Throw) }; @@ -1104,8 +1109,7 @@ class HChange: public HUnaryOperation { virtual bool DataEquals(HValue* other) { if (!other->IsChange()) return false; HChange* change = HChange::cast(other); - return value() == change->value() - && to().Equals(change->to()) + return to().Equals(change->to()) && deoptimize_on_undefined() == change->deoptimize_on_undefined(); } @@ -1254,17 +1258,21 @@ class HSimulate: public HInstruction { }; -class HStackCheck: public HTemplateInstruction<0> { +class HStackCheck: public HTemplateInstruction<1> { public: enum Type { kFunctionEntry, kBackwardsBranch }; - explicit HStackCheck(Type type) : type_(type) { } + HStackCheck(HValue* context, Type type) : type_(type) { + SetOperandAt(0, context); + } + + HValue* context() { return OperandAt(0); } virtual Representation RequiredInputRepresentation(int index) const { - return Representation::None(); + return Representation::Tagged(); } void Eliminate() { @@ -1645,19 +1653,24 @@ class HCallNew: public HBinaryCall { }; -class HCallRuntime: public HCall<0> { +class HCallRuntime: public HCall<1> { public: - HCallRuntime(Handle name, + HCallRuntime(HValue* context, + Handle name, const Runtime::Function* c_function, int argument_count) - : HCall<0>(argument_count), c_function_(c_function), name_(name) { } + : HCall<1>(argument_count), c_function_(c_function), name_(name) { + SetOperandAt(0, context); + } + virtual void PrintDataTo(StringStream* stream); + HValue* context() { return OperandAt(0); } const Runtime::Function* function() const { return c_function_; } Handle name() const { return name_; } virtual Representation RequiredInputRepresentation(int index) const { - return Representation::None(); + return Representation::Tagged(); } DECLARE_CONCRETE_INSTRUCTION(CallRuntime) @@ -1770,10 +1783,12 @@ class HBitNot: public HUnaryOperation { }; -class HUnaryMathOperation: public HUnaryOperation { +class HUnaryMathOperation: public HTemplateInstruction<2> { public: - HUnaryMathOperation(HValue* value, BuiltinFunctionId op) - : HUnaryOperation(value), op_(op) { + HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) + : op_(op) { + SetOperandAt(0, context); + SetOperandAt(1, value); switch (op) { case kMathFloor: case kMathRound: @@ -1797,6 +1812,9 @@ class HUnaryMathOperation: public HUnaryOperation { SetFlag(kUseGVN); } + HValue* context() { return OperandAt(0); } + HValue* value() { return OperandAt(1); } + virtual void PrintDataTo(StringStream* stream); virtual HType CalculateInferredType(); @@ -1804,21 +1822,25 @@ class HUnaryMathOperation: public HUnaryOperation { virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); virtual Representation RequiredInputRepresentation(int index) const { - switch (op_) { - case kMathFloor: - case kMathRound: - case kMathCeil: - case kMathSqrt: - case kMathPowHalf: - case kMathLog: - case kMathSin: - case kMathCos: - return Representation::Double(); - case kMathAbs: - return representation(); - default: - UNREACHABLE(); - return Representation::None(); + if (index == 0) { + return Representation::Tagged(); + } else { + switch (op_) { + case kMathFloor: + case kMathRound: + case kMathCeil: + case kMathSqrt: + case kMathPowHalf: + case kMathLog: + case kMathSin: + case kMathCos: + return Representation::Double(); + case kMathAbs: + return representation(); + default: + UNREACHABLE(); + return Representation::None(); + } } } @@ -2321,16 +2343,18 @@ class HConstant: public HTemplateInstruction<0> { }; -class HBinaryOperation: public HTemplateInstruction<2> { +class HBinaryOperation: public HTemplateInstruction<3> { public: - HBinaryOperation(HValue* left, HValue* right) { + HBinaryOperation(HValue* context, HValue* left, HValue* right) { ASSERT(left != NULL && right != NULL); - SetOperandAt(0, left); - SetOperandAt(1, right); + SetOperandAt(0, context); + SetOperandAt(1, left); + SetOperandAt(2, right); } - HValue* left() { return OperandAt(0); } - HValue* right() { return OperandAt(1); } + HValue* context() { return OperandAt(0); } + HValue* left() { return OperandAt(1); } + HValue* right() { return OperandAt(2); } // TODO(kasperl): Move these helpers to the IA-32 Lithium // instruction sequence builder. @@ -2446,10 +2470,11 @@ class HAccessArgumentsAt: public HTemplateInstruction<3> { }; -class HBoundsCheck: public HBinaryOperation { +class HBoundsCheck: public HTemplateInstruction<2> { public: - HBoundsCheck(HValue* index, HValue* length) - : HBinaryOperation(index, length) { + HBoundsCheck(HValue* index, HValue* length) { + SetOperandAt(0, index); + SetOperandAt(1, length); set_representation(Representation::Integer32()); SetFlag(kUseGVN); } @@ -2462,8 +2487,8 @@ class HBoundsCheck: public HBinaryOperation { virtual void Verify(); #endif - HValue* index() { return left(); } - HValue* length() { return right(); } + HValue* index() { return OperandAt(0); } + HValue* length() { return OperandAt(1); } DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) @@ -2474,15 +2499,17 @@ class HBoundsCheck: public HBinaryOperation { class HBitwiseBinaryOperation: public HBinaryOperation { public: - HBitwiseBinaryOperation(HValue* left, HValue* right) - : HBinaryOperation(left, right) { + HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) + : HBinaryOperation(context, left, right) { set_representation(Representation::Tagged()); SetFlag(kFlexibleRepresentation); SetAllSideEffects(); } virtual Representation RequiredInputRepresentation(int index) const { - return representation(); + return index == 0 + ? Representation::Tagged() + : representation(); } virtual void RepresentationChanged(Representation to) { @@ -2502,8 +2529,8 @@ class HBitwiseBinaryOperation: public HBinaryOperation { class HArithmeticBinaryOperation: public HBinaryOperation { public: - HArithmeticBinaryOperation(HValue* left, HValue* right) - : HBinaryOperation(left, right) { + HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right) + : HBinaryOperation(context, left, right) { set_representation(Representation::Tagged()); SetFlag(kFlexibleRepresentation); SetAllSideEffects(); @@ -2518,8 +2545,11 @@ class HArithmeticBinaryOperation: public HBinaryOperation { virtual HType CalculateInferredType(); virtual Representation RequiredInputRepresentation(int index) const { - return representation(); + return index == 0 + ? Representation::Tagged() + : representation(); } + virtual Representation InferredRepresentation() { if (left()->representation().Equals(right()->representation())) { return left()->representation(); @@ -2531,8 +2561,11 @@ class HArithmeticBinaryOperation: public HBinaryOperation { class HCompareGeneric: public HBinaryOperation { public: - HCompareGeneric(HValue* left, HValue* right, Token::Value token) - : HBinaryOperation(left, right), token_(token) { + HCompareGeneric(HValue* context, + HValue* left, + HValue* right, + Token::Value token) + : HBinaryOperation(context, left, right), token_(token) { ASSERT(Token::IsCompareOp(token)); set_representation(Representation::Tagged()); SetAllSideEffects(); @@ -2541,6 +2574,7 @@ class HCompareGeneric: public HBinaryOperation { virtual Representation RequiredInputRepresentation(int index) const { return Representation::Tagged(); } + Representation GetInputRepresentation() const { return Representation::Tagged(); } @@ -2614,6 +2648,7 @@ class HCompareConstantEqAndBranch: public HUnaryControlInstruction { } Token::Value op() const { return op_; } + HValue* left() { return value(); } int right() const { return right_; } virtual Representation RequiredInputRepresentation(int index) const { @@ -2796,20 +2831,14 @@ class HTypeofIsAndBranch: public HUnaryControlInstruction { }; -class HInstanceOf: public HTemplateInstruction<3> { +class HInstanceOf: public HBinaryOperation { public: - HInstanceOf(HValue* context, HValue* left, HValue* right) { - SetOperandAt(0, context); - SetOperandAt(1, left); - SetOperandAt(2, right); + HInstanceOf(HValue* context, HValue* left, HValue* right) + : HBinaryOperation(context, left, right) { set_representation(Representation::Tagged()); SetAllSideEffects(); } - HValue* context() { return OperandAt(0); } - HValue* left() { return OperandAt(1); } - HValue* right() { return OperandAt(2); } - virtual Representation RequiredInputRepresentation(int index) const { return Representation::Tagged(); } @@ -2822,14 +2851,20 @@ class HInstanceOf: public HTemplateInstruction<3> { }; -class HInstanceOfKnownGlobal: public HUnaryOperation { +class HInstanceOfKnownGlobal: public HTemplateInstruction<2> { public: - HInstanceOfKnownGlobal(HValue* left, Handle right) - : HUnaryOperation(left), function_(right) { + HInstanceOfKnownGlobal(HValue* context, + HValue* left, + Handle right) + : function_(right) { + SetOperandAt(0, context); + SetOperandAt(1, left); set_representation(Representation::Tagged()); SetAllSideEffects(); } + HValue* context() { return OperandAt(0); } + HValue* left() { return OperandAt(1); } Handle function() { return function_; } virtual Representation RequiredInputRepresentation(int index) const { @@ -2845,16 +2880,22 @@ class HInstanceOfKnownGlobal: public HUnaryOperation { }; -class HPower: public HBinaryOperation { +class HPower: public HTemplateInstruction<2> { public: - HPower(HValue* left, HValue* right) - : HBinaryOperation(left, right) { + HPower(HValue* left, HValue* right) { + SetOperandAt(0, left); + SetOperandAt(1, right); set_representation(Representation::Double()); SetFlag(kUseGVN); } + HValue* left() { return OperandAt(0); } + HValue* right() { return OperandAt(1); } + virtual Representation RequiredInputRepresentation(int index) const { - return (index == 1) ? Representation::None() : Representation::Double(); + return index == 0 + ? Representation::Double() + : Representation::None(); } DECLARE_CONCRETE_INSTRUCTION(Power) @@ -2866,7 +2907,8 @@ class HPower: public HBinaryOperation { class HAdd: public HArithmeticBinaryOperation { public: - HAdd(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { + HAdd(HValue* context, HValue* left, HValue* right) + : HArithmeticBinaryOperation(context, left, right) { SetFlag(kCanOverflow); } @@ -2891,7 +2933,8 @@ class HAdd: public HArithmeticBinaryOperation { class HSub: public HArithmeticBinaryOperation { public: - HSub(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { + HSub(HValue* context, HValue* left, HValue* right) + : HArithmeticBinaryOperation(context, left, right) { SetFlag(kCanOverflow); } @@ -2908,7 +2951,8 @@ class HSub: public HArithmeticBinaryOperation { class HMul: public HArithmeticBinaryOperation { public: - HMul(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { + HMul(HValue* context, HValue* left, HValue* right) + : HArithmeticBinaryOperation(context, left, right) { SetFlag(kCanOverflow); } @@ -2930,7 +2974,8 @@ class HMul: public HArithmeticBinaryOperation { class HMod: public HArithmeticBinaryOperation { public: - HMod(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { + HMod(HValue* context, HValue* left, HValue* right) + : HArithmeticBinaryOperation(context, left, right) { SetFlag(kCanBeDivByZero); } @@ -2957,7 +3002,8 @@ class HMod: public HArithmeticBinaryOperation { class HDiv: public HArithmeticBinaryOperation { public: - HDiv(HValue* left, HValue* right) : HArithmeticBinaryOperation(left, right) { + HDiv(HValue* context, HValue* left, HValue* right) + : HArithmeticBinaryOperation(context, left, right) { SetFlag(kCanBeDivByZero); SetFlag(kCanOverflow); } @@ -2975,8 +3021,8 @@ class HDiv: public HArithmeticBinaryOperation { class HBitAnd: public HBitwiseBinaryOperation { public: - HBitAnd(HValue* left, HValue* right) - : HBitwiseBinaryOperation(left, right) { } + HBitAnd(HValue* context, HValue* left, HValue* right) + : HBitwiseBinaryOperation(context, left, right) { } virtual bool IsCommutative() const { return true; } virtual HType CalculateInferredType(); @@ -2992,8 +3038,8 @@ class HBitAnd: public HBitwiseBinaryOperation { class HBitXor: public HBitwiseBinaryOperation { public: - HBitXor(HValue* left, HValue* right) - : HBitwiseBinaryOperation(left, right) { } + HBitXor(HValue* context, HValue* left, HValue* right) + : HBitwiseBinaryOperation(context, left, right) { } virtual bool IsCommutative() const { return true; } virtual HType CalculateInferredType(); @@ -3007,8 +3053,8 @@ class HBitXor: public HBitwiseBinaryOperation { class HBitOr: public HBitwiseBinaryOperation { public: - HBitOr(HValue* left, HValue* right) - : HBitwiseBinaryOperation(left, right) { } + HBitOr(HValue* context, HValue* left, HValue* right) + : HBitwiseBinaryOperation(context, left, right) { } virtual bool IsCommutative() const { return true; } virtual HType CalculateInferredType(); @@ -3024,8 +3070,8 @@ class HBitOr: public HBitwiseBinaryOperation { class HShl: public HBitwiseBinaryOperation { public: - HShl(HValue* left, HValue* right) - : HBitwiseBinaryOperation(left, right) { } + HShl(HValue* context, HValue* left, HValue* right) + : HBitwiseBinaryOperation(context, left, right) { } virtual Range* InferRange(); virtual HType CalculateInferredType(); @@ -3039,8 +3085,8 @@ class HShl: public HBitwiseBinaryOperation { class HShr: public HBitwiseBinaryOperation { public: - HShr(HValue* left, HValue* right) - : HBitwiseBinaryOperation(left, right) { } + HShr(HValue* context, HValue* left, HValue* right) + : HBitwiseBinaryOperation(context, left, right) { } virtual HType CalculateInferredType(); @@ -3053,8 +3099,8 @@ class HShr: public HBitwiseBinaryOperation { class HSar: public HBitwiseBinaryOperation { public: - HSar(HValue* left, HValue* right) - : HBitwiseBinaryOperation(left, right) { } + HSar(HValue* context, HValue* left, HValue* right) + : HBitwiseBinaryOperation(context, left, right) { } virtual Range* InferRange(); virtual HType CalculateInferredType(); @@ -3188,15 +3234,16 @@ class HLoadGlobalCell: public HTemplateInstruction<0> { }; -class HLoadGlobalGeneric: public HBinaryOperation { +class HLoadGlobalGeneric: public HTemplateInstruction<2> { public: HLoadGlobalGeneric(HValue* context, HValue* global_object, Handle name, bool for_typeof) - : HBinaryOperation(context, global_object), - name_(name), + : name_(name), for_typeof_(for_typeof) { + SetOperandAt(0, context); + SetOperandAt(1, global_object); set_representation(Representation::Tagged()); SetAllSideEffects(); } @@ -3319,10 +3366,12 @@ static inline bool StoringValueNeedsWriteBarrier(HValue* value) { } -class HStoreContextSlot: public HBinaryOperation { +class HStoreContextSlot: public HTemplateInstruction<2> { public: HStoreContextSlot(HValue* context, int slot_index, HValue* value) - : HBinaryOperation(context, value), slot_index_(slot_index) { + : slot_index_(slot_index) { + SetOperandAt(0, context); + SetOperandAt(1, value); SetFlag(kChangesContextSlots); } @@ -3386,13 +3435,15 @@ class HLoadNamedField: public HUnaryOperation { }; -class HLoadNamedFieldPolymorphic: public HUnaryOperation { +class HLoadNamedFieldPolymorphic: public HTemplateInstruction<2> { public: - HLoadNamedFieldPolymorphic(HValue* object, + HLoadNamedFieldPolymorphic(HValue* context, + HValue* object, ZoneMapList* types, Handle name); - HValue* object() { return OperandAt(0); } + HValue* context() { return OperandAt(0); } + HValue* object() { return OperandAt(1); } ZoneMapList* types() { return &types_; } Handle name() { return name_; } bool need_generic() { return need_generic_; } @@ -3416,10 +3467,12 @@ class HLoadNamedFieldPolymorphic: public HUnaryOperation { -class HLoadNamedGeneric: public HBinaryOperation { +class HLoadNamedGeneric: public HTemplateInstruction<2> { public: HLoadNamedGeneric(HValue* context, HValue* object, Handle name) - : HBinaryOperation(context, object), name_(name) { + : name_(name) { + SetOperandAt(0, context); + SetOperandAt(1, object); set_representation(Representation::Tagged()); SetAllSideEffects(); } @@ -3461,9 +3514,11 @@ class HLoadFunctionPrototype: public HUnaryOperation { }; -class HLoadKeyedFastElement: public HBinaryOperation { +class HLoadKeyedFastElement: public HTemplateInstruction<2> { public: - HLoadKeyedFastElement(HValue* obj, HValue* key) : HBinaryOperation(obj, key) { + HLoadKeyedFastElement(HValue* obj, HValue* key) { + SetOperandAt(0, obj); + SetOperandAt(1, key); set_representation(Representation::Tagged()); SetFlag(kDependsOnArrayElements); SetFlag(kUseGVN); @@ -3474,8 +3529,9 @@ class HLoadKeyedFastElement: public HBinaryOperation { virtual Representation RequiredInputRepresentation(int index) const { // The key is supposed to be Integer32. - return (index == 1) ? Representation::Integer32() - : Representation::Tagged(); + return index == 0 + ? Representation::Tagged() + : Representation::Integer32(); } virtual void PrintDataTo(StringStream* stream); @@ -3489,13 +3545,14 @@ class HLoadKeyedFastElement: public HBinaryOperation { }; -class HLoadKeyedSpecializedArrayElement: public HBinaryOperation { +class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> { public: HLoadKeyedSpecializedArrayElement(HValue* external_elements, HValue* key, JSObject::ElementsKind elements_kind) - : HBinaryOperation(external_elements, key), - elements_kind_(elements_kind) { + : elements_kind_(elements_kind) { + SetOperandAt(0, external_elements); + SetOperandAt(1, key); if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { set_representation(Representation::Double()); @@ -3513,8 +3570,9 @@ class HLoadKeyedSpecializedArrayElement: public HBinaryOperation { virtual Representation RequiredInputRepresentation(int index) const { // The key is supposed to be Integer32, but the base pointer // for the element load is a naked pointer. - return (index == 1) ? Representation::Integer32() - : Representation::External(); + return index == 0 + ? Representation::External() + : Representation::Integer32(); } HValue* external_pointer() { return OperandAt(0); } @@ -3560,17 +3618,18 @@ class HLoadKeyedGeneric: public HTemplateInstruction<3> { }; -class HStoreNamedField: public HBinaryOperation { +class HStoreNamedField: public HTemplateInstruction<2> { public: HStoreNamedField(HValue* obj, Handle name, HValue* val, bool in_object, int offset) - : HBinaryOperation(obj, val), - name_(name), + : name_(name), is_in_object_(in_object), offset_(offset) { + SetOperandAt(0, obj); + SetOperandAt(1, val); if (is_in_object_) { SetFlag(kChangesInobjectFields); } else { @@ -3652,7 +3711,8 @@ class HStoreKeyedFastElement: public HTemplateInstruction<3> { virtual Representation RequiredInputRepresentation(int index) const { // The key is supposed to be Integer32. - return (index == 1) ? Representation::Integer32() + return index == 1 + ? Representation::Integer32() : Representation::Tagged(); } @@ -3748,7 +3808,8 @@ class HStoreKeyedGeneric: public HTemplateInstruction<4> { class HStringAdd: public HBinaryOperation { public: - HStringAdd(HValue* left, HValue* right) : HBinaryOperation(left, right) { + HStringAdd(HValue* context, HValue* left, HValue* right) + : HBinaryOperation(context, left, right) { set_representation(Representation::Tagged()); SetFlag(kUseGVN); SetFlag(kDependsOnMaps); @@ -3769,10 +3830,12 @@ class HStringAdd: public HBinaryOperation { }; -class HStringCharCodeAt: public HBinaryOperation { +class HStringCharCodeAt: public HTemplateInstruction<3> { public: - HStringCharCodeAt(HValue* string, HValue* index) - : HBinaryOperation(string, index) { + HStringCharCodeAt(HValue* context, HValue* string, HValue* index) { + SetOperandAt(0, context); + SetOperandAt(1, string); + SetOperandAt(2, index); set_representation(Representation::Integer32()); SetFlag(kUseGVN); SetFlag(kDependsOnMaps); @@ -3780,12 +3843,14 @@ class HStringCharCodeAt: public HBinaryOperation { virtual Representation RequiredInputRepresentation(int index) const { // The index is supposed to be Integer32. - return (index == 1) ? Representation::Integer32() + return index == 2 + ? Representation::Integer32() : Representation::Tagged(); } - HValue* string() { return OperandAt(0); } - HValue* index() { return OperandAt(1); } + HValue* context() { return OperandAt(0); } + HValue* string() { return OperandAt(1); } + HValue* index() { return OperandAt(2); } DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt) @@ -3798,17 +3863,24 @@ class HStringCharCodeAt: public HBinaryOperation { }; -class HStringCharFromCode: public HUnaryOperation { +class HStringCharFromCode: public HTemplateInstruction<2> { public: - explicit HStringCharFromCode(HValue* char_code) : HUnaryOperation(char_code) { - set_representation(Representation::Tagged()); + HStringCharFromCode(HValue* context, HValue* char_code) { + SetOperandAt(0, context); + SetOperandAt(1, char_code); + set_representation(Representation::Tagged()); SetFlag(kUseGVN); } virtual Representation RequiredInputRepresentation(int index) const { - return Representation::Integer32(); + return index == 0 + ? Representation::Tagged() + : Representation::Integer32(); } + HValue* context() { return OperandAt(0); } + HValue* value() { return OperandAt(1); } + virtual bool DataEquals(HValue* other) { return true; } DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode) @@ -3860,23 +3932,27 @@ class HMaterializedLiteral: public HTemplateInstruction { }; -class HArrayLiteral: public HMaterializedLiteral<0> { +class HArrayLiteral: public HMaterializedLiteral<1> { public: - HArrayLiteral(Handle constant_elements, + HArrayLiteral(HValue* context, + Handle constant_elements, int length, int literal_index, int depth) - : HMaterializedLiteral<0>(literal_index, depth), + : HMaterializedLiteral<1>(literal_index, depth), length_(length), - constant_elements_(constant_elements) {} + constant_elements_(constant_elements) { + SetOperandAt(0, context); + } + HValue* context() { return OperandAt(0); } Handle constant_elements() const { return constant_elements_; } int length() const { return length_; } bool IsCopyOnWrite() const; virtual Representation RequiredInputRepresentation(int index) const { - return Representation::None(); + return Representation::Tagged(); } DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral) @@ -3922,20 +3998,24 @@ class HObjectLiteral: public HMaterializedLiteral<1> { }; -class HRegExpLiteral: public HMaterializedLiteral<0> { +class HRegExpLiteral: public HMaterializedLiteral<1> { public: - HRegExpLiteral(Handle pattern, + HRegExpLiteral(HValue* context, + Handle pattern, Handle flags, int literal_index) - : HMaterializedLiteral<0>(literal_index, 0), + : HMaterializedLiteral<1>(literal_index, 0), pattern_(pattern), - flags_(flags) { } + flags_(flags) { + SetOperandAt(0, context); + } + HValue* context() { return OperandAt(0); } Handle pattern() { return pattern_; } Handle flags() { return flags_; } virtual Representation RequiredInputRepresentation(int index) const { - return Representation::None(); + return Representation::Tagged(); } DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral) @@ -3946,15 +4026,20 @@ class HRegExpLiteral: public HMaterializedLiteral<0> { }; -class HFunctionLiteral: public HTemplateInstruction<0> { +class HFunctionLiteral: public HTemplateInstruction<1> { public: - HFunctionLiteral(Handle shared, bool pretenure) + HFunctionLiteral(HValue* context, + Handle shared, + bool pretenure) : shared_info_(shared), pretenure_(pretenure) { + SetOperandAt(0, context); set_representation(Representation::Tagged()); } + HValue* context() { return OperandAt(0); } + virtual Representation RequiredInputRepresentation(int index) const { - return Representation::None(); + return Representation::Tagged(); } DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral) @@ -3968,12 +4053,17 @@ class HFunctionLiteral: public HTemplateInstruction<0> { }; -class HTypeof: public HUnaryOperation { +class HTypeof: public HTemplateInstruction<2> { public: - explicit HTypeof(HValue* value) : HUnaryOperation(value) { + explicit HTypeof(HValue* context, HValue* value) { + SetOperandAt(0, context); + SetOperandAt(1, value); set_representation(Representation::Tagged()); } + HValue* context() { return OperandAt(0); } + HValue* value() { return OperandAt(1); } + virtual Representation RequiredInputRepresentation(int index) const { return Representation::Tagged(); } @@ -4016,8 +4106,8 @@ class HValueOf: public HUnaryOperation { class HDeleteProperty: public HBinaryOperation { public: - HDeleteProperty(HValue* obj, HValue* key) - : HBinaryOperation(obj, key) { + HDeleteProperty(HValue* context, HValue* obj, HValue* key) + : HBinaryOperation(context, obj, key) { set_representation(Representation::Tagged()); SetAllSideEffects(); } @@ -4035,17 +4125,19 @@ class HDeleteProperty: public HBinaryOperation { }; -class HIn: public HTemplateInstruction<2> { +class HIn: public HTemplateInstruction<3> { public: - HIn(HValue* key, HValue* object) { - SetOperandAt(0, key); - SetOperandAt(1, object); + HIn(HValue* context, HValue* key, HValue* object) { + SetOperandAt(0, context); + SetOperandAt(1, key); + SetOperandAt(2, object); set_representation(Representation::Tagged()); SetAllSideEffects(); } - HValue* key() { return OperandAt(0); } - HValue* object() { return OperandAt(1); } + HValue* context() { return OperandAt(0); } + HValue* key() { return OperandAt(1); } + HValue* object() { return OperandAt(2); } virtual Representation RequiredInputRepresentation(int index) const { return Representation::Tagged(); diff --git a/src/hydrogen.cc b/src/hydrogen.cc index dff96b4..338c12e 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -2257,7 +2257,9 @@ HGraph* HGraphBuilder::CreateGraph() { } SetupScope(scope); VisitDeclarations(scope->declarations()); - AddInstruction(new(zone()) HStackCheck(HStackCheck::kFunctionEntry)); + HValue* context = environment()->LookupContext(); + AddInstruction( + new(zone()) HStackCheck(context, HStackCheck::kFunctionEntry)); // Add an edge to the body entry. This is warty: the graph's start // environment will be used by the Lithium translation as the initial @@ -2791,8 +2793,9 @@ void HGraphBuilder::VisitLoopBody(Statement* body, HBasicBlock* loop_entry, BreakAndContinueInfo* break_info) { BreakAndContinueScope push(break_info, this); + HValue* context = environment()->LookupContext(); HStackCheck* stack_check = - new(zone()) HStackCheck(HStackCheck::kBackwardsBranch); + new(zone()) HStackCheck(context, HStackCheck::kBackwardsBranch); AddInstruction(stack_check); ASSERT(loop_entry->IsLoopHeader()); loop_entry->loop_information()->set_stack_check(stack_check); @@ -3001,8 +3004,9 @@ void HGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { } // We also have a stack overflow if the recursive compilation did. if (HasStackOverflow()) return; + HValue* context = environment()->LookupContext(); HFunctionLiteral* instr = - new(zone()) HFunctionLiteral(shared_info, expr->pretenure()); + new(zone()) HFunctionLiteral(context, shared_info, expr->pretenure()); return ast_context()->ReturnInstruction(instr, expr->id()); } @@ -3155,7 +3159,10 @@ void HGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { ASSERT(!HasStackOverflow()); ASSERT(current_block() != NULL); ASSERT(current_block()->HasPredecessor()); - HRegExpLiteral* instr = new(zone()) HRegExpLiteral(expr->pattern(), + HValue* context = environment()->LookupContext(); + + HRegExpLiteral* instr = new(zone()) HRegExpLiteral(context, + expr->pattern(), expr->flags(), expr->literal_index()); return ast_context()->ReturnInstruction(instr, expr->id()); @@ -3241,8 +3248,10 @@ void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { ASSERT(current_block()->HasPredecessor()); ZoneList* subexprs = expr->values(); int length = subexprs->length(); + HValue* context = environment()->LookupContext(); - HArrayLiteral* literal = new(zone()) HArrayLiteral(expr->constant_elements(), + HArrayLiteral* literal = new(zone()) HArrayLiteral(context, + expr->constant_elements(), length, expr->literal_index(), expr->depth()); @@ -3765,8 +3774,9 @@ void HGraphBuilder::VisitThrow(Throw* expr) { ASSERT(ast_context()->IsEffect()); CHECK_ALIVE(VisitForValue(expr->exception())); + HValue* context = environment()->LookupContext(); HValue* value = environment()->Pop(); - HThrow* instr = new(zone()) HThrow(value); + HThrow* instr = new(zone()) HThrow(context, value); instr->set_position(expr->position()); AddInstruction(instr); AddSimulate(expr->id()); @@ -4182,9 +4192,11 @@ void HGraphBuilder::VisitProperty(Property* expr) { CHECK_ALIVE(VisitForValue(expr->key())); HValue* index = Pop(); HValue* string = Pop(); - HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); + HValue* context = environment()->LookupContext(); + HStringCharCodeAt* char_code = + BuildStringCharCodeAt(context, string, index); AddInstruction(char_code); - instr = new(zone()) HStringCharFromCode(char_code); + instr = new(zone()) HStringCharFromCode(context, char_code); } else if (expr->IsFunctionPrototype()) { HValue* function = Pop(); @@ -4200,7 +4212,8 @@ void HGraphBuilder::VisitProperty(Property* expr) { instr = BuildLoadNamed(obj, expr, types->first(), name); } else if (types != NULL && types->length() > 1) { AddInstruction(new(zone()) HCheckNonSmi(obj)); - instr = new(zone()) HLoadNamedFieldPolymorphic(obj, types, name); + HValue* context = environment()->LookupContext(); + instr = new(zone()) HLoadNamedFieldPolymorphic(context, obj, types, name); } else { instr = BuildLoadNamedGeneric(obj, expr); } @@ -4604,18 +4617,20 @@ bool HGraphBuilder::TryInlineBuiltinFunction(Call* expr, if (argument_count == 2 && check_type == STRING_CHECK) { HValue* index = Pop(); HValue* string = Pop(); + HValue* context = environment()->LookupContext(); ASSERT(!expr->holder().is_null()); AddInstruction(new(zone()) HCheckPrototypeMaps( oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK), expr->holder())); - HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); + HStringCharCodeAt* char_code = + BuildStringCharCodeAt(context, string, index); if (id == kStringCharCodeAt) { ast_context()->ReturnInstruction(char_code, expr->id()); return true; } AddInstruction(char_code); HStringCharFromCode* result = - new(zone()) HStringCharFromCode(char_code); + new(zone()) HStringCharFromCode(context, char_code); ast_context()->ReturnInstruction(result, expr->id()); return true; } @@ -4630,8 +4645,10 @@ bool HGraphBuilder::TryInlineBuiltinFunction(Call* expr, if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { AddCheckConstantFunction(expr, receiver, receiver_map, true); HValue* argument = Pop(); + HValue* context = environment()->LookupContext(); Drop(1); // Receiver. - HUnaryMathOperation* op = new(zone()) HUnaryMathOperation(argument, id); + HUnaryMathOperation* op = + new(zone()) HUnaryMathOperation(context, argument, id); op->set_position(expr->position()); ast_context()->ReturnInstruction(op, expr->id()); return true; @@ -4643,31 +4660,33 @@ bool HGraphBuilder::TryInlineBuiltinFunction(Call* expr, HValue* right = Pop(); HValue* left = Pop(); Pop(); // Pop receiver. + HValue* context = environment()->LookupContext(); HInstruction* result = NULL; // Use sqrt() if exponent is 0.5 or -0.5. if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { double exponent = HConstant::cast(right)->DoubleValue(); if (exponent == 0.5) { - result = new(zone()) HUnaryMathOperation(left, kMathPowHalf); + result = + new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); } else if (exponent == -0.5) { HConstant* double_one = new(zone()) HConstant(Handle(Smi::FromInt(1)), Representation::Double()); AddInstruction(double_one); HUnaryMathOperation* square_root = - new(zone()) HUnaryMathOperation(left, kMathPowHalf); + new(zone()) HUnaryMathOperation(context, left, kMathPowHalf); AddInstruction(square_root); // MathPowHalf doesn't have side effects so there's no need for // an environment simulation here. ASSERT(!square_root->HasSideEffects()); - result = new(zone()) HDiv(double_one, square_root); + result = new(zone()) HDiv(context, double_one, square_root); } else if (exponent == 2.0) { - result = new(zone()) HMul(left, left); + result = new(zone()) HMul(context, left, left); } } else if (right->IsConstant() && HConstant::cast(right)->HasInteger32Value() && HConstant::cast(right)->Integer32Value() == 2) { - result = new(zone()) HMul(left, left); + result = new(zone()) HMul(context, left, left); } if (result == NULL) { @@ -4953,10 +4972,11 @@ void HGraphBuilder::VisitCallRuntime(CallRuntime* expr) { ASSERT(function->intrinsic_type == Runtime::RUNTIME); CHECK_ALIVE(VisitArgumentList(expr->arguments())); + HValue* context = environment()->LookupContext(); Handle name = expr->name(); int argument_count = expr->arguments()->length(); HCallRuntime* call = - new(zone()) HCallRuntime(name, function, argument_count); + new(zone()) HCallRuntime(context, name, function, argument_count); call->set_position(RelocInfo::kNoPosition); Drop(argument_count); return ast_context()->ReturnInstruction(call, expr->id()); @@ -5005,7 +5025,8 @@ void HGraphBuilder::VisitDelete(UnaryOperation* expr) { CHECK_ALIVE(VisitForValue(prop->key())); HValue* key = Pop(); HValue* obj = Pop(); - HDeleteProperty* instr = new(zone()) HDeleteProperty(obj, key); + HValue* context = environment()->LookupContext(); + HDeleteProperty* instr = new(zone()) HDeleteProperty(context, obj, key); return ast_context()->ReturnInstruction(instr, expr->id()); } } else if (var->is_global()) { @@ -5025,15 +5046,18 @@ void HGraphBuilder::VisitVoid(UnaryOperation* expr) { void HGraphBuilder::VisitTypeof(UnaryOperation* expr) { CHECK_ALIVE(VisitForTypeOf(expr->expression())); HValue* value = Pop(); - return ast_context()->ReturnInstruction(new(zone()) HTypeof(value), - expr->id()); + HValue* context = environment()->LookupContext(); + HInstruction* instr = new(zone()) HTypeof(context, value); + return ast_context()->ReturnInstruction(instr, expr->id()); } void HGraphBuilder::VisitAdd(UnaryOperation* expr) { CHECK_ALIVE(VisitForValue(expr->expression())); HValue* value = Pop(); - HInstruction* instr = new(zone()) HMul(value, graph_->GetConstant1()); + HValue* context = environment()->LookupContext(); + HInstruction* instr = + new(zone()) HMul(context, value, graph_->GetConstant1()); return ast_context()->ReturnInstruction(instr, expr->id()); } @@ -5041,7 +5065,9 @@ void HGraphBuilder::VisitAdd(UnaryOperation* expr) { void HGraphBuilder::VisitSub(UnaryOperation* expr) { CHECK_ALIVE(VisitForValue(expr->expression())); HValue* value = Pop(); - HInstruction* instr = new(zone()) HMul(value, graph_->GetConstantMinus1()); + HValue* context = environment()->LookupContext(); + HInstruction* instr = + new(zone()) HMul(context, value, graph_->GetConstantMinus1()); TypeInfo info = oracle()->UnaryType(expr); if (info.IsUninitialized()) { AddInstruction(new(zone()) HSoftDeoptimize); @@ -5138,7 +5164,8 @@ HInstruction* HGraphBuilder::BuildIncrement(bool returns_original_input, HConstant* delta = (expr->op() == Token::INC) ? graph_->GetConstant1() : graph_->GetConstantMinus1(); - HInstruction* instr = new(zone()) HAdd(Top(), delta); + HValue* context = environment()->LookupContext(); + HInstruction* instr = new(zone()) HAdd(context, Top(), delta); TraceRepresentation(expr->op(), info, instr, rep); instr->AssumeRepresentation(rep); AddInstruction(instr); @@ -5288,7 +5315,8 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { } -HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string, +HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* context, + HValue* string, HValue* index) { AddInstruction(new(zone()) HCheckNonSmi(string)); AddInstruction(HCheckInstanceType::NewIsString(string)); @@ -5296,13 +5324,14 @@ HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string, AddInstruction(length); HInstruction* checked_index = AddInstruction(new(zone()) HBoundsCheck(index, length)); - return new(zone()) HStringCharCodeAt(string, checked_index); + return new(zone()) HStringCharCodeAt(context, string, checked_index); } HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, HValue* left, HValue* right) { + HValue* context = environment()->LookupContext(); TypeInfo info = oracle()->BinaryType(expr); if (info.IsUninitialized()) { AddInstruction(new(zone()) HSoftDeoptimize); @@ -5317,40 +5346,40 @@ HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, AddInstruction(HCheckInstanceType::NewIsString(left)); AddInstruction(new(zone()) HCheckNonSmi(right)); AddInstruction(HCheckInstanceType::NewIsString(right)); - instr = new(zone()) HStringAdd(left, right); + instr = new(zone()) HStringAdd(context, left, right); } else { - instr = new(zone()) HAdd(left, right); + instr = new(zone()) HAdd(context, left, right); } break; case Token::SUB: - instr = new(zone()) HSub(left, right); + instr = new(zone()) HSub(context, left, right); break; case Token::MUL: - instr = new(zone()) HMul(left, right); + instr = new(zone()) HMul(context, left, right); break; case Token::MOD: - instr = new(zone()) HMod(left, right); + instr = new(zone()) HMod(context, left, right); break; case Token::DIV: - instr = new(zone()) HDiv(left, right); + instr = new(zone()) HDiv(context, left, right); break; case Token::BIT_XOR: - instr = new(zone()) HBitXor(left, right); + instr = new(zone()) HBitXor(context, left, right); break; case Token::BIT_AND: - instr = new(zone()) HBitAnd(left, right); + instr = new(zone()) HBitAnd(context, left, right); break; case Token::BIT_OR: - instr = new(zone()) HBitOr(left, right); + instr = new(zone()) HBitOr(context, left, right); break; case Token::SAR: - instr = new(zone()) HSar(left, right); + instr = new(zone()) HSar(context, left, right); break; case Token::SHR: - instr = new(zone()) HShr(left, right); + instr = new(zone()) HShr(context, left, right); break; case Token::SHL: - instr = new(zone()) HShl(left, right); + instr = new(zone()) HShl(context, left, right); break; default: UNREACHABLE(); @@ -5605,6 +5634,7 @@ void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { CHECK_ALIVE(VisitForValue(expr->left())); CHECK_ALIVE(VisitForValue(expr->right())); + HValue* context = environment()->LookupContext(); HValue* right = Pop(); HValue* left = Pop(); Token::Value op = expr->op(); @@ -5638,19 +5668,18 @@ void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { // If the target is not null we have found a known global function that is // assumed to stay the same for this instanceof. if (target.is_null()) { - HValue* context = environment()->LookupContext(); HInstanceOf* result = new(zone()) HInstanceOf(context, left, right); result->set_position(expr->position()); return ast_context()->ReturnInstruction(result, expr->id()); } else { AddInstruction(new(zone()) HCheckFunction(right, target)); HInstanceOfKnownGlobal* result = - new(zone()) HInstanceOfKnownGlobal(left, target); + new(zone()) HInstanceOfKnownGlobal(context, left, target); result->set_position(expr->position()); return ast_context()->ReturnInstruction(result, expr->id()); } } else if (op == Token::IN) { - HIn* result = new(zone()) HIn(left, right); + HIn* result = new(zone()) HIn(context, left, right); result->set_position(expr->position()); return ast_context()->ReturnInstruction(result, expr->id()); } else if (type_info.IsNonPrimitive()) { @@ -5682,7 +5711,8 @@ void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { } else { Representation r = ToRepresentation(type_info); if (r.IsTagged()) { - HCompareGeneric* result = new(zone()) HCompareGeneric(left, right, op); + HCompareGeneric* result = + new(zone()) HCompareGeneric(context, left, right, op); result->set_position(expr->position()); return ast_context()->ReturnInstruction(result, expr->id()); } else { @@ -5898,7 +5928,8 @@ void HGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); HValue* index = Pop(); HValue* string = Pop(); - HStringCharCodeAt* result = BuildStringCharCodeAt(string, index); + HValue* context = environment()->LookupContext(); + HStringCharCodeAt* result = BuildStringCharCodeAt(context, string, index); return ast_context()->ReturnInstruction(result, call->id()); } @@ -5908,7 +5939,9 @@ void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { ASSERT(call->arguments()->length() == 1); CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); HValue* char_code = Pop(); - HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code); + HValue* context = environment()->LookupContext(); + HStringCharFromCode* result = + new(zone()) HStringCharFromCode(context, char_code); return ast_context()->ReturnInstruction(result, call->id()); } @@ -5920,9 +5953,11 @@ void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) { CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); HValue* index = Pop(); HValue* string = Pop(); - HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index); + HValue* context = environment()->LookupContext(); + HStringCharCodeAt* char_code = BuildStringCharCodeAt(context, string, index); AddInstruction(char_code); - HStringCharFromCode* result = new(zone()) HStringCharFromCode(char_code); + HStringCharFromCode* result = + new(zone()) HStringCharFromCode(context, char_code); return ast_context()->ReturnInstruction(result, call->id()); } diff --git a/src/hydrogen.h b/src/hydrogen.h index bd5ef6a..c53d7f7 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -904,7 +904,8 @@ class HGraphBuilder: public AstVisitor { void HandleLiteralCompareUndefined(CompareOperation* compare_expr, Expression* expr); - HStringCharCodeAt* BuildStringCharCodeAt(HValue* string, + HStringCharCodeAt* BuildStringCharCodeAt(HValue* context, + HValue* string, HValue* index); HInstruction* BuildBinaryOperation(BinaryOperation* expr, HValue* left, diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 080b2a0..ec1adb9 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -428,15 +428,11 @@ void LCodeGen::AddToTranslation(Translation* translation, void LCodeGen::CallCodeGeneric(Handle code, RelocInfo::Mode mode, LInstruction* instr, - ContextMode context_mode, SafepointMode safepoint_mode) { ASSERT(instr != NULL); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); - if (context_mode == RESTORE_CONTEXT) { - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); - } __ call(code, mode); RegisterLazyDeoptimization(instr, safepoint_mode); @@ -452,24 +448,19 @@ void LCodeGen::CallCodeGeneric(Handle code, void LCodeGen::CallCode(Handle code, RelocInfo::Mode mode, - LInstruction* instr, - ContextMode context_mode) { - CallCodeGeneric(code, mode, instr, context_mode, RECORD_SIMPLE_SAFEPOINT); + LInstruction* instr) { + CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT); } void LCodeGen::CallRuntime(const Runtime::Function* fun, int argc, - LInstruction* instr, - ContextMode context_mode) { + LInstruction* instr) { ASSERT(instr != NULL); ASSERT(instr->HasPointerMap()); LPointerMap* pointers = instr->pointer_map(); RecordPosition(pointers->position()); - if (context_mode == RESTORE_CONTEXT) { - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); - } __ CallRuntime(fun, argc); RegisterLazyDeoptimization(instr, RECORD_SIMPLE_SAFEPOINT); @@ -478,8 +469,18 @@ void LCodeGen::CallRuntime(const Runtime::Function* fun, void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, int argc, - LInstruction* instr) { - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); + LInstruction* instr, + LOperand* context) { + ASSERT(context->IsRegister() || context->IsStackSlot()); + if (context->IsRegister()) { + if (!ToRegister(context).is(esi)) { + __ mov(esi, ToRegister(context)); + } + } else { + // Context is stack slot. + __ mov(esi, ToOperand(context)); + } + __ CallRuntimeSaveDoubles(id); RecordSafepointWithRegisters( instr->pointer_map(), argc, Safepoint::kNoDeoptimizationIndex); @@ -748,38 +749,38 @@ void LCodeGen::DoCallStub(LCallStub* instr) { switch (instr->hydrogen()->major_key()) { case CodeStub::RegExpConstructResult: { RegExpConstructResultStub stub; - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); break; } case CodeStub::RegExpExec: { RegExpExecStub stub; - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); break; } case CodeStub::SubString: { SubStringStub stub; - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); break; } case CodeStub::NumberToString: { NumberToStringStub stub; - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); break; } case CodeStub::StringAdd: { StringAddStub stub(NO_STRING_ADD_FLAGS); - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); break; } case CodeStub::StringCompare: { StringCompareStub stub; - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); break; } case CodeStub::TranscendentalCache: { TranscendentalCacheStub stub(instr->transcendental_type(), TranscendentalCacheStub::TAGGED); - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); break; } default: @@ -1256,8 +1257,9 @@ void LCodeGen::DoBitNotI(LBitNotI* instr) { void LCodeGen::DoThrow(LThrow* instr) { - __ push(ToOperand(instr->InputAt(0))); - CallRuntime(Runtime::kThrow, 1, instr, RESTORE_CONTEXT); + __ push(ToOperand(instr->value())); + ASSERT(ToRegister(instr->context()).is(esi)); + CallRuntime(Runtime::kThrow, 1, instr); if (FLAG_debug_code) { Comment("Unreachable code."); @@ -1327,12 +1329,13 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) { void LCodeGen::DoArithmeticT(LArithmeticT* instr) { - ASSERT(ToRegister(instr->InputAt(0)).is(edx)); - ASSERT(ToRegister(instr->InputAt(1)).is(eax)); + ASSERT(ToRegister(instr->context()).is(esi)); + ASSERT(ToRegister(instr->left()).is(edx)); + ASSERT(ToRegister(instr->right()).is(eax)); ASSERT(ToRegister(instr->result()).is(eax)); BinaryOpStub stub(instr->op(), NO_OVERWRITE); - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); } @@ -1767,7 +1770,7 @@ void LCodeGen::DoInstanceOf(LInstanceOf* instr) { // Object and function are in fixed registers defined by the stub. ASSERT(ToRegister(instr->context()).is(esi)); InstanceofStub stub(InstanceofStub::kArgsInRegisters); - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); Label true_value, done; __ test(eax, Operand(eax)); @@ -1801,7 +1804,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { deferred = new DeferredInstanceOfKnownGlobal(this, instr); Label done, false_result; - Register object = ToRegister(instr->InputAt(0)); + Register object = ToRegister(instr->InputAt(1)); Register temp = ToRegister(instr->TempAt(0)); // A Smi is not an instance of anything. @@ -1863,14 +1866,13 @@ void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, Register temp = ToRegister(instr->TempAt(0)); ASSERT(MacroAssembler::SafepointRegisterStackIndex(temp) == 0); __ mov(InstanceofStub::right(), Immediate(instr->function())); - static const int kAdditionalDelta = 16; + static const int kAdditionalDelta = 13; int delta = masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; __ mov(temp, Immediate(delta)); __ StoreToSafepointRegisterSlot(temp, temp); CallCodeGeneric(stub.GetCode(), RelocInfo::CODE_TARGET, instr, - RESTORE_CONTEXT, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); // Put the result value into the eax slot and restore all registers. __ StoreToSafepointRegisterSlot(eax, eax); @@ -1901,7 +1903,7 @@ void LCodeGen::DoCmpT(LCmpT* instr) { Token::Value op = instr->op(); Handle ic = CompareIC::GetUninitialized(op); - CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); + CallCode(ic, RelocInfo::CODE_TARGET, instr); Condition condition = ComputeCompareCondition(op); if (op == Token::GT || op == Token::LTE) { @@ -1953,7 +1955,7 @@ void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET : RelocInfo::CODE_TARGET_CONTEXT; Handle ic = isolate()->builtins()->LoadIC_Initialize(); - CallCode(ic, mode, instr, CONTEXT_ADJUSTED); + CallCode(ic, mode, instr); } @@ -1984,7 +1986,7 @@ void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { Handle ic = instr->strict_mode() ? isolate()->builtins()->StoreIC_Initialize_Strict() : isolate()->builtins()->StoreIC_Initialize(); - CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr, CONTEXT_ADJUSTED); + CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); } @@ -2056,7 +2058,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { ASSERT(instr->hydrogen()->need_generic()); __ mov(ecx, name); Handle ic = isolate()->builtins()->LoadIC_Initialize(); - CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); + CallCode(ic, RelocInfo::CODE_TARGET, instr); } else { Label done; for (int i = 0; i < map_count - 1; ++i) { @@ -2078,7 +2080,7 @@ void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { __ bind(&generic); __ mov(ecx, name); Handle ic = isolate()->builtins()->LoadIC_Initialize(); - CallCode(ic, RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); + CallCode(ic, RelocInfo::CODE_TARGET, instr); } else { DeoptimizeIf(not_equal, instr->environment()); EmitLoadFieldOrConstantFunction(result, object, map, name); @@ -2095,7 +2097,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { __ mov(ecx, instr->name()); Handle ic = isolate()->builtins()->LoadIC_Initialize(); - CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); + CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -2294,7 +2296,7 @@ void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { ASSERT(ToRegister(instr->key()).is(eax)); Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); - CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); + CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -2524,7 +2526,7 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { - Register input_reg = ToRegister(instr->InputAt(0)); + Register input_reg = ToRegister(instr->value()); __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), factory()->heap_number_map()); DeoptimizeIf(not_equal, instr->environment()); @@ -2555,7 +2557,8 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { // Slow case: Call the runtime system to do the number allocation. __ bind(&slow); - CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); + CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, + instr, instr->context()); // Set the pointer to the new heap number in tmp. if (!tmp.is(eax)) __ mov(tmp, eax); @@ -2576,7 +2579,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { - Register input_reg = ToRegister(instr->InputAt(0)); + Register input_reg = ToRegister(instr->value()); __ test(input_reg, Operand(input_reg)); Label is_positive; __ j(not_sign, &is_positive); @@ -2601,12 +2604,12 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { LUnaryMathOperation* instr_; }; - ASSERT(instr->InputAt(0)->Equals(instr->result())); + ASSERT(instr->value()->Equals(instr->result())); Representation r = instr->hydrogen()->value()->representation(); if (r.IsDouble()) { XMMRegister scratch = xmm0; - XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); + XMMRegister input_reg = ToDoubleRegister(instr->value()); __ xorps(scratch, scratch); __ subsd(scratch, input_reg); __ pand(input_reg, scratch); @@ -2615,7 +2618,7 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { } else { // Tagged case. DeferredMathAbsTaggedHeapNumber* deferred = new DeferredMathAbsTaggedHeapNumber(this, instr); - Register input_reg = ToRegister(instr->InputAt(0)); + Register input_reg = ToRegister(instr->value()); // Smi check. __ JumpIfNotSmi(input_reg, deferred->entry()); EmitIntegerMathAbs(instr); @@ -2627,7 +2630,7 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { XMMRegister xmm_scratch = xmm0; Register output_reg = ToRegister(instr->result()); - XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); + XMMRegister input_reg = ToDoubleRegister(instr->value()); __ xorps(xmm_scratch, xmm_scratch); // Zero the register. __ ucomisd(input_reg, xmm_scratch); @@ -2649,7 +2652,7 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { XMMRegister xmm_scratch = xmm0; Register output_reg = ToRegister(instr->result()); - XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); + XMMRegister input_reg = ToDoubleRegister(instr->value()); Label below_half, done; // xmm_scratch = 0.5 @@ -2694,7 +2697,7 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { - XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); + XMMRegister input_reg = ToDoubleRegister(instr->value()); ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); __ sqrtsd(input_reg, input_reg); } @@ -2702,7 +2705,7 @@ void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { XMMRegister xmm_scratch = xmm0; - XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); + XMMRegister input_reg = ToDoubleRegister(instr->value()); ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); __ xorps(xmm_scratch, xmm_scratch); __ addsd(input_reg, xmm_scratch); // Convert -0 to +0. @@ -2770,8 +2773,8 @@ void LCodeGen::DoPower(LPower* instr) { void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { - ASSERT(instr->InputAt(0)->Equals(instr->result())); - XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); + ASSERT(instr->value()->Equals(instr->result())); + XMMRegister input_reg = ToDoubleRegister(instr->value()); Label positive, done, zero; __ xorps(xmm0, xmm0); __ ucomisd(input_reg, xmm0); @@ -2803,7 +2806,7 @@ void LCodeGen::DoMathCos(LUnaryMathOperation* instr) { ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); TranscendentalCacheStub stub(TranscendentalCache::COS, TranscendentalCacheStub::UNTAGGED); - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); } @@ -2811,7 +2814,7 @@ void LCodeGen::DoMathSin(LUnaryMathOperation* instr) { ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); TranscendentalCacheStub stub(TranscendentalCache::SIN, TranscendentalCacheStub::UNTAGGED); - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); } @@ -2871,7 +2874,7 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) { int arity = instr->arity(); Handle ic = isolate()->stub_cache()-> ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); - CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); + CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -2884,7 +2887,7 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) { Handle ic = isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); __ mov(ecx, instr->name()); - CallCode(ic, mode, instr, CONTEXT_ADJUSTED); + CallCode(ic, mode, instr); } @@ -2894,7 +2897,7 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) { int arity = instr->arity(); CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT); - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); __ Drop(1); } @@ -2908,7 +2911,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) { Handle ic = isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); __ mov(ecx, instr->name()); - CallCode(ic, mode, instr, CONTEXT_ADJUSTED); + CallCode(ic, mode, instr); } @@ -2926,12 +2929,12 @@ void LCodeGen::DoCallNew(LCallNew* instr) { Handle builtin = isolate()->builtins()->JSConstructCall(); __ Set(eax, Immediate(instr->arity())); - CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr, CONTEXT_ADJUSTED); + CallCode(builtin, RelocInfo::CONSTRUCT_CALL, instr); } void LCodeGen::DoCallRuntime(LCallRuntime* instr) { - CallRuntime(instr->function(), instr->arity(), instr, RESTORE_CONTEXT); + CallRuntime(instr->function(), instr->arity(), instr); } @@ -2974,7 +2977,7 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { Handle ic = instr->strict_mode() ? isolate()->builtins()->StoreIC_Initialize_Strict() : isolate()->builtins()->StoreIC_Initialize(); - CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); + CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -3064,7 +3067,7 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { Handle ic = instr->strict_mode() ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() : isolate()->builtins()->KeyedStoreIC_Initialize(); - CallCode(ic, RelocInfo::CODE_TARGET, instr, CONTEXT_ADJUSTED); + CallCode(ic, RelocInfo::CODE_TARGET, instr); } @@ -3195,7 +3198,8 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { __ SmiTag(index); __ push(index); } - CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, instr); + CallRuntimeFromDeferred(Runtime::kStringCharCodeAt, 2, + instr, instr->context()); if (FLAG_debug_code) { __ AbortIfNotSmi(eax); } @@ -3246,7 +3250,7 @@ void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { PushSafepointRegistersScope scope(this); __ SmiTag(char_code); __ push(char_code); - CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr); + CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context()); __ StoreToSafepointRegisterSlot(result, eax); } @@ -3270,7 +3274,7 @@ void LCodeGen::DoStringAdd(LStringAdd* instr) { __ push(ToOperand(instr->right())); } StringAddStub stub(NO_STRING_CHECK_IN_STUB); - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); } @@ -3331,8 +3335,15 @@ void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { // register is stored, as this register is in the pointer map, but contains an // integer value. __ StoreToSafepointRegisterSlot(reg, Immediate(0)); - - CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); + // NumberTagI and NumberTagD use the context from the frame, rather than + // the environment's HContext or HInlinedContext value. + // They only call Runtime::kAllocateHeapNumber. + // The corresponding HChange instructions are added in a phase that does + // not have easy access to the local context. + __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); + __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); + RecordSafepointWithRegisters( + instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); if (!reg.is(eax)) __ mov(reg, eax); // Done. Put the value in xmm0 into the value of the allocated heap @@ -3376,7 +3387,15 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { __ Set(reg, Immediate(0)); PushSafepointRegistersScope scope(this); - CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); + // NumberTagI and NumberTagD use the context from the frame, rather than + // the environment's HContext or HInlinedContext value. + // They only call Runtime::kAllocateHeapNumber. + // The corresponding HChange instructions are added in a phase that does + // not have easy access to the local context. + __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); + __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); + RecordSafepointWithRegisters(instr->pointer_map(), 0, + Safepoint::kNoDeoptimizationIndex); __ StoreToSafepointRegisterSlot(reg, eax); } @@ -3846,6 +3865,7 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { + ASSERT(ToRegister(instr->context()).is(esi)); // Setup the parameters to the stub/runtime call. __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); __ push(FieldOperand(eax, JSFunction::kLiteralsOffset)); @@ -3859,16 +3879,16 @@ void LCodeGen::DoArrayLiteral(LArrayLiteral* instr) { FastCloneShallowArrayStub::Mode mode = FastCloneShallowArrayStub::COPY_ON_WRITE_ELEMENTS; FastCloneShallowArrayStub stub(mode, length); - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); } else if (instr->hydrogen()->depth() > 1) { - CallRuntime(Runtime::kCreateArrayLiteral, 3, instr, RESTORE_CONTEXT); + CallRuntime(Runtime::kCreateArrayLiteral, 3, instr); } else if (length > FastCloneShallowArrayStub::kMaximumClonedLength) { - CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr, RESTORE_CONTEXT); + CallRuntime(Runtime::kCreateArrayLiteralShallow, 3, instr); } else { FastCloneShallowArrayStub::Mode mode = FastCloneShallowArrayStub::CLONE_ELEMENTS; FastCloneShallowArrayStub stub(mode, length); - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); } } @@ -3890,12 +3910,9 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { // Pick the right runtime function to call. if (instr->hydrogen()->depth() > 1) { - CallRuntime(Runtime::kCreateObjectLiteral, 4, instr, CONTEXT_ADJUSTED); + CallRuntime(Runtime::kCreateObjectLiteral, 4, instr); } else { - CallRuntime(Runtime::kCreateObjectLiteralShallow, - 4, - instr, - CONTEXT_ADJUSTED); + CallRuntime(Runtime::kCreateObjectLiteralShallow, 4, instr); } } @@ -3903,17 +3920,19 @@ void LCodeGen::DoObjectLiteral(LObjectLiteral* instr) { void LCodeGen::DoToFastProperties(LToFastProperties* instr) { ASSERT(ToRegister(instr->InputAt(0)).is(eax)); __ push(eax); - CallRuntime(Runtime::kToFastProperties, 1, instr, CONTEXT_ADJUSTED); + CallRuntime(Runtime::kToFastProperties, 1, instr); } void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { + ASSERT(ToRegister(instr->context()).is(esi)); Label materialized; // Registers will be used as follows: // edi = JS function. // ecx = literals array. // ebx = regexp literal. // eax = regexp literal clone. + // esi = context. __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); __ mov(ecx, FieldOperand(edi, JSFunction::kLiteralsOffset)); int literal_offset = FixedArray::kHeaderSize + @@ -3928,7 +3947,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { __ push(Immediate(Smi::FromInt(instr->hydrogen()->literal_index()))); __ push(Immediate(instr->hydrogen()->pattern())); __ push(Immediate(instr->hydrogen()->flags())); - CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr, RESTORE_CONTEXT); + CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr); __ mov(ebx, eax); __ bind(&materialized); @@ -3940,7 +3959,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { __ bind(&runtime_allocate); __ push(ebx); __ push(Immediate(Smi::FromInt(size))); - CallRuntime(Runtime::kAllocateInNewSpace, 1, instr, RESTORE_CONTEXT); + CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); __ pop(ebx); __ bind(&allocated); @@ -3960,6 +3979,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { + ASSERT(ToRegister(instr->context()).is(esi)); // Use the fast case closure allocation code that allocates in new // space for nested functions that don't need literals cloning. Handle shared_info = instr->shared_info(); @@ -3968,26 +3988,26 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { FastNewClosureStub stub( shared_info->strict_mode() ? kStrictMode : kNonStrictMode); __ push(Immediate(shared_info)); - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); } else { __ push(Operand(ebp, StandardFrameConstants::kContextOffset)); __ push(Immediate(shared_info)); __ push(Immediate(pretenure ? factory()->true_value() : factory()->false_value())); - CallRuntime(Runtime::kNewClosure, 3, instr, RESTORE_CONTEXT); + CallRuntime(Runtime::kNewClosure, 3, instr); } } void LCodeGen::DoTypeof(LTypeof* instr) { - LOperand* input = instr->InputAt(0); + LOperand* input = instr->InputAt(1); if (input->IsConstantOperand()) { __ push(ToImmediate(input)); } else { __ push(ToOperand(input)); } - CallRuntime(Runtime::kTypeof, 1, instr, RESTORE_CONTEXT); + CallRuntime(Runtime::kTypeof, 1, instr); } @@ -4130,7 +4150,6 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { SafepointGenerator safepoint_generator(this, pointers, env->deoptimization_index()); - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); __ push(Immediate(Smi::FromInt(strict_mode_flag()))); __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, safepoint_generator); } @@ -4138,7 +4157,7 @@ void LCodeGen::DoDeleteProperty(LDeleteProperty* instr) { void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { PushSafepointRegistersScope scope(this); - CallRuntimeFromDeferred(Runtime::kStackGuard, 0, instr); + CallRuntimeFromDeferred(Runtime::kStackGuard, 0, instr, instr->context()); } @@ -4160,8 +4179,10 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) { __ cmp(esp, Operand::StaticVariable(stack_limit)); __ j(above_equal, &done, Label::kNear); + ASSERT(instr->context()->IsRegister()); + ASSERT(ToRegister(instr->context()).is(esi)); StackCheckStub stub; - CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr, RESTORE_CONTEXT); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); __ bind(&done); } else { ASSERT(instr->hydrogen()->is_backwards_branch()); @@ -4219,7 +4240,6 @@ void LCodeGen::DoIn(LIn* instr) { SafepointGenerator safepoint_generator(this, pointers, env->deoptimization_index()); - __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); } diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h index defbcab..ecd2f51 100644 --- a/src/ia32/lithium-codegen-ia32.h +++ b/src/ia32/lithium-codegen-ia32.h @@ -166,11 +166,6 @@ class LCodeGen BASE_EMBEDDED { bool GenerateRelocPadding(); bool GenerateSafepointTable(); - enum ContextMode { - RESTORE_CONTEXT, - CONTEXT_ADJUSTED - }; - enum SafepointMode { RECORD_SIMPLE_SAFEPOINT, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS @@ -178,31 +173,28 @@ class LCodeGen BASE_EMBEDDED { void CallCode(Handle code, RelocInfo::Mode mode, - LInstruction* instr, - ContextMode context_mode); + LInstruction* instr); void CallCodeGeneric(Handle code, RelocInfo::Mode mode, LInstruction* instr, - ContextMode context_mode, SafepointMode safepoint_mode); void CallRuntime(const Runtime::Function* fun, int argc, - LInstruction* instr, - ContextMode context_mode); + LInstruction* instr); void CallRuntime(Runtime::FunctionId id, int argc, - LInstruction* instr, - ContextMode context_mode) { + LInstruction* instr) { const Runtime::Function* function = Runtime::FunctionForId(id); - CallRuntime(function, argc, instr, context_mode); + CallRuntime(function, argc, instr); } void CallRuntimeFromDeferred(Runtime::FunctionId id, int argc, - LInstruction* instr); + LInstruction* instr, + LOperand* context); // Generate a direct call to a known function. Expects the function // to be in edi. diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index db69047..1b9aeb5 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -811,9 +811,10 @@ LInstruction* LChunkBuilder::DoBit(Token::Value op, ASSERT(instr->left()->representation().IsTagged()); ASSERT(instr->right()->representation().IsTagged()); + LOperand* context = UseFixed(instr->context(), esi); LOperand* left = UseFixed(instr->left(), edx); LOperand* right = UseFixed(instr->right(), eax); - LArithmeticT* result = new LArithmeticT(op, left, right); + LArithmeticT* result = new LArithmeticT(op, context, left, right); return MarkAsCall(DefineFixed(result, eax), instr); } } @@ -825,18 +826,19 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op, ASSERT(instr->left()->representation().IsTagged()); ASSERT(instr->right()->representation().IsTagged()); + LOperand* context = UseFixed(instr->context(), esi); LOperand* left = UseFixed(instr->left(), edx); LOperand* right = UseFixed(instr->right(), eax); - LArithmeticT* result = new LArithmeticT(op, left, right); + LArithmeticT* result = new LArithmeticT(op, context, left, right); return MarkAsCall(DefineFixed(result, eax), instr); } ASSERT(instr->representation().IsInteger32()); - ASSERT(instr->OperandAt(0)->representation().IsInteger32()); - ASSERT(instr->OperandAt(1)->representation().IsInteger32()); - LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); + ASSERT(instr->left()->representation().IsInteger32()); + ASSERT(instr->right()->representation().IsInteger32()); + LOperand* left = UseRegisterAtStart(instr->left()); - HValue* right_value = instr->OperandAt(1); + HValue* right_value = instr->right(); LOperand* right = NULL; int constant_value = 0; if (right_value->IsConstant()) { @@ -890,12 +892,15 @@ LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, HValue* right = instr->right(); ASSERT(left->representation().IsTagged()); ASSERT(right->representation().IsTagged()); + LOperand* context = UseFixed(instr->context(), esi); LOperand* left_operand = UseFixed(left, edx); LOperand* right_operand = UseFixed(right, eax); - LArithmeticT* result = new LArithmeticT(op, left_operand, right_operand); + LArithmeticT* result = + new LArithmeticT(op, context, left_operand, right_operand); return MarkAsCall(DefineFixed(result, eax), instr); } + void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { ASSERT(is_building()); current_block_ = block; @@ -1061,7 +1066,8 @@ LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( HInstanceOfKnownGlobal* instr) { LInstanceOfKnownGlobal* result = new LInstanceOfKnownGlobal( - UseFixed(instr->value(), InstanceofStub::left()), + UseFixed(instr->context(), esi), + UseFixed(instr->left(), InstanceofStub::left()), FixedTemp(edi)); return MarkAsCall(DefineFixed(result, eax), instr); } @@ -1138,16 +1144,19 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { if (op == kMathLog) { ASSERT(instr->representation().IsDouble()); ASSERT(instr->value()->representation().IsDouble()); + LOperand* context = UseAny(instr->context()); // Not actually used. LOperand* input = UseRegisterAtStart(instr->value()); - LUnaryMathOperation* result = new LUnaryMathOperation(input); + LUnaryMathOperation* result = new LUnaryMathOperation(context, input); return DefineSameAsFirst(result); } else if (op == kMathSin || op == kMathCos) { + LOperand* context = UseFixed(instr->context(), esi); LOperand* input = UseFixedDouble(instr->value(), xmm1); - LUnaryMathOperation* result = new LUnaryMathOperation(input); + LUnaryMathOperation* result = new LUnaryMathOperation(context, input); return MarkAsCall(DefineFixedDouble(result, xmm1), instr); } else { LOperand* input = UseRegisterAtStart(instr->value()); - LUnaryMathOperation* result = new LUnaryMathOperation(input); + LOperand* context = UseAny(instr->context()); // Deferred use by MathAbs. + LUnaryMathOperation* result = new LUnaryMathOperation(context, input); switch (op) { case kMathAbs: return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); @@ -1218,7 +1227,8 @@ LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) { argument_count_ -= instr->argument_count(); - return MarkAsCall(DefineFixed(new LCallRuntime, eax), instr); + LOperand* context = UseFixed(instr->context(), esi); + return MarkAsCall(DefineFixed(new LCallRuntime(context), eax), instr); } @@ -1403,9 +1413,10 @@ LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) { ASSERT(instr->left()->representation().IsTagged()); ASSERT(instr->right()->representation().IsTagged()); bool reversed = (op == Token::GT || op == Token::LTE); + LOperand* context = UseFixed(instr->context(), esi); LOperand* left = UseFixed(instr->left(), reversed ? eax : edx); LOperand* right = UseFixed(instr->right(), reversed ? edx : eax); - LCmpT* result = new LCmpT(left, right); + LCmpT* result = new LCmpT(context, left, right); return MarkAsCall(DefineFixed(result, eax), instr); } @@ -1552,8 +1563,9 @@ LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) { LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { + LOperand* context = UseFixed(instr->context(), esi); LOperand* value = UseFixed(instr->value(), eax); - return MarkAsCall(new LThrow(value), instr); + return MarkAsCall(new LThrow(context, value), instr); } @@ -1811,13 +1823,16 @@ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic( HLoadNamedFieldPolymorphic* instr) { ASSERT(instr->representation().IsTagged()); + LOperand* context = UseFixed(instr->context(), esi); if (instr->need_generic()) { LOperand* obj = UseFixed(instr->object(), eax); - LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj); + LLoadNamedFieldPolymorphic* result = + new LLoadNamedFieldPolymorphic(context, obj); return MarkAsCall(DefineFixed(result, eax), instr); } else { LOperand* obj = UseRegisterAtStart(instr->object()); - LLoadNamedFieldPolymorphic* result = new LLoadNamedFieldPolymorphic(obj); + LLoadNamedFieldPolymorphic* result = + new LLoadNamedFieldPolymorphic(context, obj); return AssignEnvironment(DefineAsRegister(result)); } } @@ -1998,23 +2013,27 @@ LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) { + LOperand* context = UseFixed(instr->context(), esi); LOperand* left = UseOrConstantAtStart(instr->left()); LOperand* right = UseOrConstantAtStart(instr->right()); - return MarkAsCall(DefineFixed(new LStringAdd(left, right), eax), instr); + LStringAdd* string_add = new LStringAdd(context, left, right); + return MarkAsCall(DefineFixed(string_add, eax), instr); } LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) { LOperand* string = UseRegister(instr->string()); LOperand* index = UseRegisterOrConstant(instr->index()); - LStringCharCodeAt* result = new LStringCharCodeAt(string, index); + LOperand* context = UseAny(instr->context()); + LStringCharCodeAt* result = new LStringCharCodeAt(context, string, index); return AssignEnvironment(AssignPointerMap(DefineAsRegister(result))); } LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) { LOperand* char_code = UseRegister(instr->value()); - LStringCharFromCode* result = new LStringCharFromCode(char_code); + LOperand* context = UseAny(instr->context()); + LStringCharFromCode* result = new LStringCharFromCode(context, char_code); return AssignPointerMap(DefineAsRegister(result)); } @@ -2026,7 +2045,8 @@ LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) { LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { - return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); + LOperand* context = UseFixed(instr->context(), esi); + return MarkAsCall(DefineFixed(new LArrayLiteral(context), eax), instr); } @@ -2037,19 +2057,22 @@ LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { - return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr); + LOperand* context = UseFixed(instr->context(), esi); + return MarkAsCall(DefineFixed(new LRegExpLiteral(context), eax), instr); } LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { - return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr); + LOperand* context = UseFixed(instr->context(), esi); + return MarkAsCall(DefineFixed(new LFunctionLiteral(context), eax), instr); } LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { - LDeleteProperty* result = - new LDeleteProperty(UseAtStart(instr->object()), - UseOrConstantAtStart(instr->key())); + LOperand* context = UseFixed(instr->context(), esi); + LOperand* object = UseAtStart(instr->object()); + LOperand* key = UseOrConstantAtStart(instr->key()); + LDeleteProperty* result = new LDeleteProperty(context, object, key); return MarkAsCall(DefineFixed(result, eax), instr); } @@ -2111,7 +2134,9 @@ LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) { LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { - LTypeof* result = new LTypeof(UseAtStart(instr->value())); + LOperand* context = UseFixed(instr->context(), esi); + LOperand* value = UseAtStart(instr->value()); + LTypeof* result = new LTypeof(context, value); return MarkAsCall(DefineFixed(result, eax), instr); } @@ -2161,10 +2186,12 @@ LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { if (instr->is_function_entry()) { - return MarkAsCall(new LStackCheck, instr); + LOperand* context = UseFixed(instr->context(), esi); + return MarkAsCall(new LStackCheck(context), instr); } else { ASSERT(instr->is_backwards_branch()); - return AssignEnvironment(AssignPointerMap(new LStackCheck)); + LOperand* context = UseAny(instr->context()); + return AssignEnvironment(AssignPointerMap(new LStackCheck(context))); } } @@ -2190,9 +2217,10 @@ LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { LInstruction* LChunkBuilder::DoIn(HIn* instr) { + LOperand* context = UseFixed(instr->context(), esi); LOperand* key = UseOrConstantAtStart(instr->key()); LOperand* object = UseOrConstantAtStart(instr->object()); - LIn* result = new LIn(key, object); + LIn* result = new LIn(context, key, object); return MarkAsCall(DefineFixed(result, eax), instr); } diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index 5f4dd25..0daab5f 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -572,12 +572,16 @@ class LCmpIDAndBranch: public LControlInstruction<2, 0> { }; -class LUnaryMathOperation: public LTemplateInstruction<1, 1, 0> { +class LUnaryMathOperation: public LTemplateInstruction<1, 2, 0> { public: - explicit LUnaryMathOperation(LOperand* value) { + LUnaryMathOperation(LOperand* context, LOperand* value) { + inputs_[1] = context; inputs_[0] = value; } + LOperand* context() { return inputs_[1]; } + LOperand* value() { return inputs_[0]; } + DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation") DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation) @@ -654,7 +658,7 @@ class LIsSmiAndBranch: public LControlInstruction<1, 0> { class LIsUndetectableAndBranch: public LControlInstruction<1, 1> { public: - explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) { + LIsUndetectableAndBranch(LOperand* value, LOperand* temp) { inputs_[0] = value; temps_[0] = temp; } @@ -731,11 +735,12 @@ class LClassOfTestAndBranch: public LControlInstruction<1, 2> { }; -class LCmpT: public LTemplateInstruction<1, 2, 0> { +class LCmpT: public LTemplateInstruction<1, 3, 0> { public: - LCmpT(LOperand* left, LOperand* right) { - inputs_[0] = left; - inputs_[1] = right; + LCmpT(LOperand* context, LOperand* left, LOperand* right) { + inputs_[0] = context; + inputs_[1] = left; + inputs_[2] = right; } DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t") @@ -759,10 +764,11 @@ class LInstanceOf: public LTemplateInstruction<1, 3, 0> { }; -class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> { +class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 2, 1> { public: - LInstanceOfKnownGlobal(LOperand* value, LOperand* temp) { - inputs_[0] = value; + LInstanceOfKnownGlobal(LOperand* context, LOperand* value, LOperand* temp) { + inputs_[0] = context; + inputs_[1] = value; temps_[0] = temp; } @@ -958,12 +964,16 @@ class LValueOf: public LTemplateInstruction<1, 1, 1> { }; -class LThrow: public LTemplateInstruction<0, 1, 0> { +class LThrow: public LTemplateInstruction<0, 2, 0> { public: - explicit LThrow(LOperand* value) { - inputs_[0] = value; + LThrow(LOperand* context, LOperand* value) { + inputs_[0] = context; + inputs_[1] = value; } + LOperand* context() { return inputs_[0]; } + LOperand* value() { return inputs_[1]; } + DECLARE_CONCRETE_INSTRUCTION(Throw, "throw") }; @@ -1021,12 +1031,16 @@ class LArithmeticD: public LTemplateInstruction<1, 2, 0> { }; -class LArithmeticT: public LTemplateInstruction<1, 2, 0> { +class LArithmeticT: public LTemplateInstruction<1, 3, 0> { public: - LArithmeticT(Token::Value op, LOperand* left, LOperand* right) + LArithmeticT(Token::Value op, + LOperand* context, + LOperand* left, + LOperand* right) : op_(op) { - inputs_[0] = left; - inputs_[1] = right; + inputs_[0] = context; + inputs_[1] = left; + inputs_[2] = right; } virtual Opcode opcode() const { return LInstruction::kArithmeticT; } @@ -1034,6 +1048,9 @@ class LArithmeticT: public LTemplateInstruction<1, 2, 0> { virtual const char* Mnemonic() const; Token::Value op() const { return op_; } + LOperand* context() { return inputs_[0]; } + LOperand* left() { return inputs_[1]; } + LOperand* right() { return inputs_[2]; } private: Token::Value op_; @@ -1063,16 +1080,18 @@ class LLoadNamedField: public LTemplateInstruction<1, 1, 0> { }; -class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 1, 0> { +class LLoadNamedFieldPolymorphic: public LTemplateInstruction<1, 2, 0> { public: - explicit LLoadNamedFieldPolymorphic(LOperand* object) { - inputs_[0] = object; + LLoadNamedFieldPolymorphic(LOperand* context, LOperand* object) { + inputs_[0] = context; + inputs_[1] = object; } DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field-polymorphic") DECLARE_HYDROGEN_ACCESSOR(LoadNamedFieldPolymorphic) - LOperand* object() { return inputs_[0]; } + LOperand* context() { return inputs_[0]; } + LOperand* object() { return inputs_[1]; } }; @@ -1215,9 +1234,9 @@ class LStoreGlobalCell: public LTemplateInstruction<0, 1, 0> { class LStoreGlobalGeneric: public LTemplateInstruction<0, 3, 0> { public: - explicit LStoreGlobalGeneric(LOperand* context, - LOperand* global_object, - LOperand* value) { + LStoreGlobalGeneric(LOperand* context, + LOperand* global_object, + LOperand* value) { inputs_[0] = context; inputs_[1] = global_object; inputs_[2] = value; @@ -1455,11 +1474,15 @@ class LCallNew: public LTemplateInstruction<1, 2, 0> { }; -class LCallRuntime: public LTemplateInstruction<1, 0, 0> { +class LCallRuntime: public LTemplateInstruction<1, 1, 0> { public: + explicit LCallRuntime(LOperand* context) { + inputs_[0] = context; + } DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime") DECLARE_HYDROGEN_ACCESSOR(CallRuntime) + LOperand* context() { return inputs_[0]; } const Runtime::Function* function() const { return hydrogen()->function(); } int arity() const { return hydrogen()->argument_count(); } }; @@ -1676,46 +1699,52 @@ class LStoreKeyedGeneric: public LTemplateInstruction<0, 4, 0> { }; -class LStringAdd: public LTemplateInstruction<1, 2, 0> { +class LStringAdd: public LTemplateInstruction<1, 3, 0> { public: - LStringAdd(LOperand* left, LOperand* right) { - inputs_[0] = left; - inputs_[1] = right; + LStringAdd(LOperand* context, LOperand* left, LOperand* right) { + inputs_[0] = context; + inputs_[1] = left; + inputs_[2] = right; } DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add") DECLARE_HYDROGEN_ACCESSOR(StringAdd) - LOperand* left() { return inputs_[0]; } - LOperand* right() { return inputs_[1]; } + LOperand* context() { return inputs_[0]; } + LOperand* left() { return inputs_[1]; } + LOperand* right() { return inputs_[2]; } }; -class LStringCharCodeAt: public LTemplateInstruction<1, 2, 0> { +class LStringCharCodeAt: public LTemplateInstruction<1, 3, 0> { public: - LStringCharCodeAt(LOperand* string, LOperand* index) { - inputs_[0] = string; - inputs_[1] = index; + LStringCharCodeAt(LOperand* context, LOperand* string, LOperand* index) { + inputs_[0] = context; + inputs_[1] = string; + inputs_[2] = index; } DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at") DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt) - LOperand* string() { return inputs_[0]; } - LOperand* index() { return inputs_[1]; } + LOperand* context() { return inputs_[0]; } + LOperand* string() { return inputs_[1]; } + LOperand* index() { return inputs_[2]; } }; -class LStringCharFromCode: public LTemplateInstruction<1, 1, 0> { +class LStringCharFromCode: public LTemplateInstruction<1, 2, 0> { public: - explicit LStringCharFromCode(LOperand* char_code) { - inputs_[0] = char_code; + LStringCharFromCode(LOperand* context, LOperand* char_code) { + inputs_[0] = context; + inputs_[1] = char_code; } DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code") DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode) - LOperand* char_code() { return inputs_[0]; } + LOperand* context() { return inputs_[0]; } + LOperand* char_code() { return inputs_[1]; } }; @@ -1837,8 +1866,14 @@ class LCheckNonSmi: public LTemplateInstruction<0, 1, 0> { }; -class LArrayLiteral: public LTemplateInstruction<1, 0, 0> { +class LArrayLiteral: public LTemplateInstruction<1, 1, 0> { public: + explicit LArrayLiteral(LOperand* context) { + inputs_[0] = context; + } + + LOperand* context() { return inputs_[0]; } + DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal") DECLARE_HYDROGEN_ACCESSOR(ArrayLiteral) }; @@ -1850,22 +1885,34 @@ class LObjectLiteral: public LTemplateInstruction<1, 1, 0> { inputs_[0] = context; } + LOperand* context() { return inputs_[0]; } + DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal") DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral) - - LOperand* context() { return inputs_[0]; } }; -class LRegExpLiteral: public LTemplateInstruction<1, 0, 0> { +class LRegExpLiteral: public LTemplateInstruction<1, 1, 0> { public: + explicit LRegExpLiteral(LOperand* context) { + inputs_[0] = context; + } + + LOperand* context() { return inputs_[0]; } + DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal") DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral) }; -class LFunctionLiteral: public LTemplateInstruction<1, 0, 0> { +class LFunctionLiteral: public LTemplateInstruction<1, 1, 0> { public: + explicit LFunctionLiteral(LOperand* context) { + inputs_[0] = context; + } + + LOperand* context() { return inputs_[0]; } + DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal") DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral) @@ -1884,10 +1931,11 @@ class LToFastProperties: public LTemplateInstruction<1, 1, 0> { }; -class LTypeof: public LTemplateInstruction<1, 1, 0> { +class LTypeof: public LTemplateInstruction<1, 2, 0> { public: - explicit LTypeof(LOperand* value) { - inputs_[0] = value; + LTypeof(LOperand* context, LOperand* value) { + inputs_[0] = context; + inputs_[1] = value; } DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof") @@ -1909,17 +1957,19 @@ class LTypeofIsAndBranch: public LControlInstruction<1, 0> { }; -class LDeleteProperty: public LTemplateInstruction<1, 2, 0> { +class LDeleteProperty: public LTemplateInstruction<1, 3, 0> { public: - LDeleteProperty(LOperand* obj, LOperand* key) { - inputs_[0] = obj; - inputs_[1] = key; + LDeleteProperty(LOperand* context, LOperand* obj, LOperand* key) { + inputs_[0] = context; + inputs_[1] = obj; + inputs_[2] = key; } DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property") - LOperand* object() { return inputs_[0]; } - LOperand* key() { return inputs_[1]; } + LOperand* context() { return inputs_[0]; } + LOperand* object() { return inputs_[1]; } + LOperand* key() { return inputs_[2]; } }; @@ -1946,8 +1996,14 @@ class LOsrEntry: public LTemplateInstruction<0, 0, 0> { }; -class LStackCheck: public LTemplateInstruction<0, 0, 0> { +class LStackCheck: public LTemplateInstruction<0, 1, 0> { public: + explicit LStackCheck(LOperand* context) { + inputs_[0] = context; + } + + LOperand* context() { return inputs_[0]; } + DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check") DECLARE_HYDROGEN_ACCESSOR(StackCheck) @@ -1958,15 +2014,17 @@ class LStackCheck: public LTemplateInstruction<0, 0, 0> { }; -class LIn: public LTemplateInstruction<1, 2, 0> { +class LIn: public LTemplateInstruction<1, 3, 0> { public: - LIn(LOperand* key, LOperand* object) { - inputs_[0] = key; - inputs_[1] = object; + LIn(LOperand* context, LOperand* key, LOperand* object) { + inputs_[0] = context; + inputs_[1] = key; + inputs_[2] = object; } - LOperand* key() { return inputs_[0]; } - LOperand* object() { return inputs_[1]; } + LOperand* context() { return inputs_[0]; } + LOperand* key() { return inputs_[1]; } + LOperand* object() { return inputs_[2]; } DECLARE_CONCRETE_INSTRUCTION(In, "in") }; @@ -1975,7 +2033,7 @@ class LIn: public LTemplateInstruction<1, 2, 0> { class LChunkBuilder; class LChunk: public ZoneObject { public: - explicit LChunk(CompilationInfo* info, HGraph* graph) + LChunk(CompilationInfo* info, HGraph* graph) : spill_slot_count_(0), info_(info), graph_(graph), diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 58c4521..b2994cd 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -831,11 +831,11 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op, } ASSERT(instr->representation().IsInteger32()); - ASSERT(instr->OperandAt(0)->representation().IsInteger32()); - ASSERT(instr->OperandAt(1)->representation().IsInteger32()); - LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); + ASSERT(instr->left()->representation().IsInteger32()); + ASSERT(instr->right()->representation().IsInteger32()); + LOperand* left = UseRegisterAtStart(instr->left()); - HValue* right_value = instr->OperandAt(1); + HValue* right_value = instr->right(); LOperand* right = NULL; int constant_value = 0; if (right_value->IsConstant()) { @@ -1059,7 +1059,7 @@ LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( HInstanceOfKnownGlobal* instr) { LInstanceOfKnownGlobal* result = - new LInstanceOfKnownGlobal(UseFixed(instr->value(), rax), + new LInstanceOfKnownGlobal(UseFixed(instr->left(), rax), FixedTemp(rdi)); return MarkAsCall(DefineFixed(result, rax), instr); } -- 2.7.4