| Index: src/ia32/code-stubs-ia32.h
|
| diff --git a/src/ia32/code-stubs-ia32.h b/src/ia32/code-stubs-ia32.h
|
| index 343044e078c1c68706a320de724374cebfc5c844..63b9486e8a5fa4b8a8376a634a7945ff964502b4 100644
|
| --- a/src/ia32/code-stubs-ia32.h
|
| +++ b/src/ia32/code-stubs-ia32.h
|
| @@ -83,7 +83,7 @@ class GenericBinaryOpStub: public CodeStub {
|
| args_in_registers_(false),
|
| args_reversed_(false),
|
| static_operands_type_(operands_type),
|
| - runtime_operands_type_(BinaryOpIC::DEFAULT),
|
| + runtime_operands_type_(BinaryOpIC::UNINIT_OR_SMI),
|
| name_(NULL) {
|
| if (static_operands_type_.IsSmi()) {
|
| mode_ = NO_OVERWRITE;
|
| @@ -117,6 +117,11 @@ class GenericBinaryOpStub: public CodeStub {
|
| || op_ == Token::MUL || op_ == Token::DIV;
|
| }
|
|
|
| + void SetArgsInRegisters() {
|
| + ASSERT(ArgsInRegistersSupported());
|
| + args_in_registers_ = true;
|
| + }
|
| +
|
| private:
|
| Token::Value op_;
|
| OverwriteMode mode_;
|
| @@ -157,7 +162,7 @@ class GenericBinaryOpStub: public CodeStub {
|
| class ArgsReversedBits: public BitField<bool, 11, 1> {};
|
| class FlagBits: public BitField<GenericBinaryFlags, 12, 1> {};
|
| class StaticTypeInfoBits: public BitField<int, 13, 3> {};
|
| - class RuntimeTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 16, 2> {};
|
| + class RuntimeTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 16, 3> {};
|
|
|
| Major MajorKey() { return GenericBinaryOp; }
|
| int MinorKey() {
|
| @@ -185,7 +190,6 @@ class GenericBinaryOpStub: public CodeStub {
|
| return (op_ == Token::ADD) || (op_ == Token::MUL);
|
| }
|
|
|
| - void SetArgsInRegisters() { args_in_registers_ = true; }
|
| void SetArgsReversed() { args_reversed_ = true; }
|
| bool HasSmiCodeInStub() { return (flags_ & NO_SMI_CODE_IN_STUB) == 0; }
|
| bool HasArgsInRegisters() { return args_in_registers_; }
|
| @@ -207,6 +211,123 @@ class GenericBinaryOpStub: public CodeStub {
|
| return BinaryOpIC::ToState(runtime_operands_type_);
|
| }
|
|
|
| + virtual void FinishCode(Code* code) {
|
| + code->set_binary_op_type(runtime_operands_type_);
|
| + }
|
| +
|
| + friend class CodeGenerator;
|
| +};
|
| +
|
| +
|
| +class TypeRecordingBinaryOpStub: public CodeStub {
|
| + public:
|
| + TypeRecordingBinaryOpStub(Token::Value op, OverwriteMode mode)
|
| + : op_(op),
|
| + mode_(mode),
|
| + operands_type_(TRBinaryOpIC::UNINITIALIZED),
|
| + result_type_(TRBinaryOpIC::UNINITIALIZED),
|
| + name_(NULL) {
|
| + use_sse3_ = Isolate::Current()->cpu_features()->IsSupported(SSE3);
|
| + ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
|
| + }
|
| +
|
| + TypeRecordingBinaryOpStub(int key,
|
| + TRBinaryOpIC::TypeInfo operands_type,
|
| + TRBinaryOpIC::TypeInfo result_type = TRBinaryOpIC::UNINITIALIZED)
|
| + : op_(OpBits::decode(key)),
|
| + mode_(ModeBits::decode(key)),
|
| + use_sse3_(SSE3Bits::decode(key)),
|
| + operands_type_(operands_type),
|
| + result_type_(result_type),
|
| + name_(NULL) {
|
| + }
|
| +
|
| + // Generate code to call the stub with the supplied arguments. This will add
|
| + // code at the call site to prepare arguments either in registers or on the
|
| + // stack together with the actual call.
|
| + void GenerateCall(MacroAssembler* masm, Register left, Register right);
|
| + void GenerateCall(MacroAssembler* masm, Register left, Smi* right);
|
| + void GenerateCall(MacroAssembler* masm, Smi* left, Register right);
|
| +
|
| + private:
|
| + enum SmiCodeGenerateHeapNumberResults {
|
| + ALLOW_HEAPNUMBER_RESULTS,
|
| + NO_HEAPNUMBER_RESULTS
|
| + };
|
| +
|
| + Token::Value op_;
|
| + OverwriteMode mode_;
|
| + bool use_sse3_;
|
| +
|
| + // Operand type information determined at runtime.
|
| + TRBinaryOpIC::TypeInfo operands_type_;
|
| + TRBinaryOpIC::TypeInfo result_type_;
|
| +
|
| + char* name_;
|
| +
|
| + const char* GetName();
|
| +
|
| +#ifdef DEBUG
|
| + void Print() {
|
| + PrintF("TypeRecordingBinaryOpStub %d (op %s), "
|
| + "(mode %d, runtime_type_info %s)\n",
|
| + MinorKey(),
|
| + Token::String(op_),
|
| + static_cast<int>(mode_),
|
| + TRBinaryOpIC::GetName(operands_type_));
|
| + }
|
| +#endif
|
| +
|
| + // Minor key encoding in 16 bits RRRTTTSOOOOOOOMM.
|
| + class ModeBits: public BitField<OverwriteMode, 0, 2> {};
|
| + class OpBits: public BitField<Token::Value, 2, 7> {};
|
| + class SSE3Bits: public BitField<bool, 9, 1> {};
|
| + class OperandTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 10, 3> {};
|
| + class ResultTypeInfoBits: public BitField<TRBinaryOpIC::TypeInfo, 13, 3> {};
|
| +
|
| + Major MajorKey() { return TypeRecordingBinaryOp; }
|
| + int MinorKey() {
|
| + return OpBits::encode(op_)
|
| + | ModeBits::encode(mode_)
|
| + | SSE3Bits::encode(use_sse3_)
|
| + | OperandTypeInfoBits::encode(operands_type_)
|
| + | ResultTypeInfoBits::encode(result_type_);
|
| + }
|
| +
|
| + void Generate(MacroAssembler* masm);
|
| + void GenerateGeneric(MacroAssembler* masm);
|
| + void GenerateSmiCode(MacroAssembler* masm,
|
| + Label* slow,
|
| + SmiCodeGenerateHeapNumberResults heapnumber_results);
|
| + void GenerateLoadArguments(MacroAssembler* masm);
|
| + void GenerateReturn(MacroAssembler* masm);
|
| + void GenerateUninitializedStub(MacroAssembler* masm);
|
| + void GenerateSmiStub(MacroAssembler* masm);
|
| + void GenerateInt32Stub(MacroAssembler* masm);
|
| + void GenerateHeapNumberStub(MacroAssembler* masm);
|
| + void GenerateStringStub(MacroAssembler* masm);
|
| + void GenerateGenericStub(MacroAssembler* masm);
|
| +
|
| + void GenerateHeapResultAllocation(MacroAssembler* masm, Label* alloc_failure);
|
| + void GenerateRegisterArgsPush(MacroAssembler* masm);
|
| + void GenerateTypeTransition(MacroAssembler* masm);
|
| + void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm);
|
| +
|
| + bool IsOperationCommutative() {
|
| + return (op_ == Token::ADD) || (op_ == Token::MUL);
|
| + }
|
| +
|
| + virtual int GetCodeKind() { return Code::TYPE_RECORDING_BINARY_OP_IC; }
|
| +
|
| + virtual InlineCacheState GetICState() {
|
| + return TRBinaryOpIC::ToState(operands_type_);
|
| + }
|
| +
|
| + virtual void FinishCode(Code* code) {
|
| + code->set_type_recording_binary_op_type(operands_type_);
|
| + code->set_type_recording_binary_op_result_type(result_type_);
|
| + }
|
| +
|
| friend class CodeGenerator;
|
| };
|
|
|
|
|