diff options
Diffstat (limited to 'deps/v8/src/ia32/code-stubs-ia32.h')
-rw-r--r-- | deps/v8/src/ia32/code-stubs-ia32.h | 127 |
1 files changed, 124 insertions, 3 deletions
diff --git a/deps/v8/src/ia32/code-stubs-ia32.h b/deps/v8/src/ia32/code-stubs-ia32.h index 351636faf7..2973101877 100644 --- a/deps/v8/src/ia32/code-stubs-ia32.h +++ b/deps/v8/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_ = CpuFeatures::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; }; |