Chromium Code Reviews| Index: src/code-stubs.h |
| diff --git a/src/code-stubs.h b/src/code-stubs.h |
| index a843841723cb2102b9787cacc5a24013538eaa60..af3072284e2b61f8b7a218331622e3b50a173a85 100644 |
| --- a/src/code-stubs.h |
| +++ b/src/code-stubs.h |
| @@ -482,10 +482,132 @@ class MathPowStub: public CodeStub { |
| }; |
| +class BinaryOpStub: public CodeStub { |
| + public: |
| + BinaryOpStub(Token::Value op, OverwriteMode mode) |
| + : op_(op), |
| + mode_(mode), |
| + platform_specific_bit_(false), |
| + left_type_(BinaryOpIC::UNINITIALIZED), |
| + right_type_(BinaryOpIC::UNINITIALIZED), |
| + result_type_(BinaryOpIC::UNINITIALIZED) { |
| + Initialize(); |
| + ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); |
| + } |
| + |
| + BinaryOpStub( |
| + int key, |
| + BinaryOpIC::TypeInfo left_type, |
| + BinaryOpIC::TypeInfo right_type, |
| + BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED) |
| + : op_(OpBits::decode(key)), |
| + mode_(ModeBits::decode(key)), |
| + platform_specific_bit_(PlatformSpecificBits::decode(key)), |
| + left_type_(left_type), |
| + right_type_(right_type), |
| + result_type_(result_type) { } |
| + |
| + static void decode_types_from_minor_key(int minor_key, |
| + BinaryOpIC::TypeInfo* left_type, |
| + BinaryOpIC::TypeInfo* right_type, |
| + BinaryOpIC::TypeInfo* result_type) { |
| + *left_type = |
| + static_cast<BinaryOpIC::TypeInfo>(LeftTypeBits::decode(minor_key)); |
| + *right_type = |
| + static_cast<BinaryOpIC::TypeInfo>(RightTypeBits::decode(minor_key)); |
| + *result_type= |
|
danno
2012/11/06 11:42:59
nit: space after type
Jakob Kummerow
2012/11/06 12:44:05
Done.
|
| + static_cast<BinaryOpIC::TypeInfo>(ResultTypeBits::decode(minor_key)); |
| + } |
| + |
| + static Token::Value decode_op_from_minor_key(int minor_key) { |
| + return static_cast<Token::Value>(OpBits::decode(minor_key)); |
| + } |
| + |
| + enum SmiCodeGenerateHeapNumberResults { |
| + ALLOW_HEAPNUMBER_RESULTS, |
| + NO_HEAPNUMBER_RESULTS |
| + }; |
| + |
| + private: |
| + Token::Value op_; |
| + OverwriteMode mode_; |
| + bool platform_specific_bit_; // Indicates SSE3 on IA32, VFP2 on ARM. |
| + |
| + // Operand type information determined at runtime. |
| + BinaryOpIC::TypeInfo left_type_; |
| + BinaryOpIC::TypeInfo right_type_; |
| + BinaryOpIC::TypeInfo result_type_; |
| + |
| + virtual void PrintName(StringStream* stream); |
| + |
| + // Minor key encoding in 19 bits TTTRRRLLLSOOOOOOOMM. |
| + class ModeBits: public BitField<OverwriteMode, 0, 2> {}; |
| + class OpBits: public BitField<Token::Value, 2, 7> {}; |
| + class PlatformSpecificBits: public BitField<bool, 9, 1> {}; |
| + class LeftTypeBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {}; |
| + class RightTypeBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {}; |
| + class ResultTypeBits: public BitField<BinaryOpIC::TypeInfo, 16, 3> {}; |
| + |
| + Major MajorKey() { return BinaryOp; } |
| + int MinorKey() { |
| + return OpBits::encode(op_) |
| + | ModeBits::encode(mode_) |
| + | PlatformSpecificBits::encode(platform_specific_bit_) |
| + | LeftTypeBits::encode(left_type_) |
| + | RightTypeBits::encode(right_type_) |
| + | ResultTypeBits::encode(result_type_); |
| + } |
| + |
| + |
| + // Platform-independent implementation. |
| + void Generate(MacroAssembler* masm); |
| + void GenerateCallRuntime(MacroAssembler* masm); |
| + |
| + // Platform-independent signature, platform-specific implementation. |
| + void Initialize(); |
| + void GenerateAddStrings(MacroAssembler* masm); |
| + void GenerateBothStringStub(MacroAssembler* masm); |
| + void GenerateGeneric(MacroAssembler* masm); |
| + void GenerateGenericStub(MacroAssembler* masm); |
| + void GenerateHeapNumberStub(MacroAssembler* masm); |
| + void GenerateInt32Stub(MacroAssembler* masm); |
| + void GenerateLoadArguments(MacroAssembler* masm); |
| + void GenerateOddballStub(MacroAssembler* masm); |
| + void GenerateRegisterArgsPush(MacroAssembler* masm); |
| + void GenerateReturn(MacroAssembler* masm); |
| + void GenerateSmiStub(MacroAssembler* masm); |
| + void GenerateStringStub(MacroAssembler* masm); |
| + void GenerateTypeTransition(MacroAssembler* masm); |
| + void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm); |
| + void GenerateUninitializedStub(MacroAssembler* masm); |
| + |
| + // Entirely platform-specific methods are defined as static helper |
| + // functions in the <arch>/code-stubs-<arch>.cc files. |
| + |
| + virtual int GetCodeKind() { return Code::BINARY_OP_IC; } |
| + |
| + virtual InlineCacheState GetICState() { |
| + return BinaryOpIC::ToState(Max(left_type_, right_type_)); |
| + } |
| + |
| + virtual void FinishCode(Handle<Code> code) { |
| + code->set_stub_info(MinorKey()); |
| + } |
| + |
| + friend class CodeGenerator; |
| +}; |
| + |
| + |
| class ICCompareStub: public CodeStub { |
| public: |
| - ICCompareStub(Token::Value op, CompareIC::State state) |
| - : op_(op), state_(state) { |
| + ICCompareStub(Token::Value op, |
| + CompareIC::State left, |
| + CompareIC::State right, |
| + CompareIC::State handler) |
| + : op_(op), |
| + left_(left), |
| + right_(right), |
| + state_(handler) { |
| ASSERT(Token::IsCompareOp(op)); |
| } |
| @@ -493,13 +615,24 @@ class ICCompareStub: public CodeStub { |
| void set_known_map(Handle<Map> map) { known_map_ = map; } |
| + static void DecodeMinorKey(int minor_key, |
| + CompareIC::State* left_state, |
| + CompareIC::State* right_state, |
| + CompareIC::State* handler_state, |
| + Token::Value* op); |
| + |
| + static CompareIC::State CompareState(int minor_key) { |
| + return static_cast<CompareIC::State>(HandlerStateField::decode(minor_key)); |
| + } |
| + |
| private: |
| class OpField: public BitField<int, 0, 3> { }; |
| - class StateField: public BitField<int, 3, 5> { }; |
| + class LeftStateField: public BitField<int, 3, 3> { }; |
| + class RightStateField: public BitField<int, 6, 3> { }; |
| + class HandlerStateField: public BitField<int, 9, 3> { }; |
| virtual void FinishCode(Handle<Code> code) { |
| - code->set_compare_state(state_); |
| - code->set_compare_operation(op_ - Token::EQ); |
| + code->set_stub_info(MinorKey()); |
| } |
| virtual CodeStub::Major MajorKey() { return CompareIC; } |
| @@ -514,6 +647,7 @@ class ICCompareStub: public CodeStub { |
| void GenerateObjects(MacroAssembler* masm); |
| void GenerateMiss(MacroAssembler* masm); |
| void GenerateKnownObjects(MacroAssembler* masm); |
| + void GenerateGeneric(MacroAssembler* masm); |
| bool strict() const { return op_ == Token::EQ_STRICT; } |
| Condition GetCondition() const { return CompareIC::ComputeCondition(op_); } |
| @@ -523,108 +657,13 @@ class ICCompareStub: public CodeStub { |
| virtual bool UseSpecialCache() { return state_ == CompareIC::KNOWN_OBJECTS; } |
| Token::Value op_; |
| + CompareIC::State left_; |
| + CompareIC::State right_; |
| CompareIC::State state_; |
| Handle<Map> known_map_; |
| }; |
| -// Flags that control the compare stub code generation. |
| -enum CompareFlags { |
| - NO_COMPARE_FLAGS = 0, |
| - NO_SMI_COMPARE_IN_STUB = 1 << 0, |
| - NO_NUMBER_COMPARE_IN_STUB = 1 << 1, |
| - CANT_BOTH_BE_NAN = 1 << 2 |
| -}; |
| - |
| - |
| -enum NaNInformation { |
| - kBothCouldBeNaN, |
| - kCantBothBeNaN |
| -}; |
| - |
| - |
| -class CompareStub: public CodeStub { |
| - public: |
| - CompareStub(Condition cc, |
| - bool strict, |
| - CompareFlags flags, |
| - Register lhs, |
| - Register rhs) : |
| - cc_(cc), |
| - strict_(strict), |
| - never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0), |
| - include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0), |
| - include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0), |
| - lhs_(lhs), |
| - rhs_(rhs) { } |
| - |
| - CompareStub(Condition cc, |
| - bool strict, |
| - CompareFlags flags) : |
| - cc_(cc), |
| - strict_(strict), |
| - never_nan_nan_((flags & CANT_BOTH_BE_NAN) != 0), |
| - include_number_compare_((flags & NO_NUMBER_COMPARE_IN_STUB) == 0), |
| - include_smi_compare_((flags & NO_SMI_COMPARE_IN_STUB) == 0), |
| - lhs_(no_reg), |
| - rhs_(no_reg) { } |
| - |
| - void Generate(MacroAssembler* masm); |
| - |
| - private: |
| - Condition cc_; |
| - bool strict_; |
| - // Only used for 'equal' comparisons. Tells the stub that we already know |
| - // that at least one side of the comparison is not NaN. This allows the |
| - // stub to use object identity in the positive case. We ignore it when |
| - // generating the minor key for other comparisons to avoid creating more |
| - // stubs. |
| - bool never_nan_nan_; |
| - // Do generate the number comparison code in the stub. Stubs without number |
| - // comparison code is used when the number comparison has been inlined, and |
| - // the stub will be called if one of the operands is not a number. |
| - bool include_number_compare_; |
| - |
| - // Generate the comparison code for two smi operands in the stub. |
| - bool include_smi_compare_; |
| - |
| - // Register holding the left hand side of the comparison if the stub gives |
| - // a choice, no_reg otherwise. |
| - |
| - Register lhs_; |
| - // Register holding the right hand side of the comparison if the stub gives |
| - // a choice, no_reg otherwise. |
| - Register rhs_; |
| - |
| - // Encoding of the minor key in 16 bits. |
| - class StrictField: public BitField<bool, 0, 1> {}; |
| - class NeverNanNanField: public BitField<bool, 1, 1> {}; |
| - class IncludeNumberCompareField: public BitField<bool, 2, 1> {}; |
| - class IncludeSmiCompareField: public BitField<bool, 3, 1> {}; |
| - class RegisterField: public BitField<bool, 4, 1> {}; |
| - class ConditionField: public BitField<int, 5, 11> {}; |
| - |
| - Major MajorKey() { return Compare; } |
| - |
| - int MinorKey(); |
| - |
| - virtual int GetCodeKind() { return Code::COMPARE_IC; } |
| - virtual void FinishCode(Handle<Code> code) { |
| - code->set_compare_state(CompareIC::GENERIC); |
| - } |
| - |
| - // Branch to the label if the given object isn't a symbol. |
| - void BranchIfNonSymbol(MacroAssembler* masm, |
| - Label* label, |
| - Register object, |
| - Register scratch); |
| - |
| - // Unfortunately you have to run without snapshots to see most of these |
| - // names in the profile since most compare stubs end up in the snapshot. |
| - virtual void PrintName(StringStream* stream); |
| -}; |
| - |
| - |
| class CEntryStub : public CodeStub { |
| public: |
| explicit CEntryStub(int result_size, |
| @@ -1053,6 +1092,9 @@ class ToBooleanStub: public CodeStub { |
| bool IsEmpty() const { return set_.IsEmpty(); } |
| bool Contains(Type type) const { return set_.Contains(type); } |
| + bool ContainsAnyOf(Types types) const { |
| + return set_.ContainsAnyOf(types.set_); |
| + } |
| void Add(Type type) { set_.Add(type); } |
| byte ToByte() const { return set_.ToIntegral(); } |
| void Print(StringStream* stream) const; |