Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: src/code-stubs.h

Issue 25494007: Reland "Hydrogenisation of binops" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebase Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ast.h ('k') | src/code-stubs.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 978 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 Isolate* isolate, 989 Isolate* isolate,
990 CodeStubInterfaceDescriptor* descriptor); 990 CodeStubInterfaceDescriptor* descriptor);
991 991
992 virtual Handle<Code> GenerateCode(Isolate* isolate); 992 virtual Handle<Code> GenerateCode(Isolate* isolate);
993 993
994 private: 994 private:
995 virtual CodeStub::Major MajorKey() { return KeyedLoadField; } 995 virtual CodeStub::Major MajorKey() { return KeyedLoadField; }
996 }; 996 };
997 997
998 998
999 class BinaryOpStub: public PlatformCodeStub { 999 class BinaryOpStub: public HydrogenCodeStub {
1000 public: 1000 public:
1001 BinaryOpStub(Token::Value op, OverwriteMode mode) 1001 BinaryOpStub(Token::Value op, OverwriteMode mode)
1002 : op_(op), 1002 : HydrogenCodeStub(UNINITIALIZED), op_(op), mode_(mode) {
1003 mode_(mode), 1003 ASSERT(op <= LAST_TOKEN && op >= FIRST_TOKEN);
1004 platform_specific_bit_(false),
1005 left_type_(BinaryOpIC::UNINITIALIZED),
1006 right_type_(BinaryOpIC::UNINITIALIZED),
1007 result_type_(BinaryOpIC::UNINITIALIZED),
1008 encoded_right_arg_(false, encode_arg_value(1)) {
1009 Initialize(); 1004 Initialize();
1010 ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
1011 } 1005 }
1012 1006
1013 BinaryOpStub( 1007 explicit BinaryOpStub(Code::ExtraICState state)
1014 int key, 1008 : op_(decode_token(OpBits::decode(state))),
1015 BinaryOpIC::TypeInfo left_type, 1009 mode_(OverwriteModeField::decode(state)),
1016 BinaryOpIC::TypeInfo right_type, 1010 fixed_right_arg_(
1017 BinaryOpIC::TypeInfo result_type, 1011 Maybe<int>(HasFixedRightArgBits::decode(state),
1018 Maybe<int32_t> fixed_right_arg) 1012 decode_arg_value(FixedRightArgValueBits::decode(state)))),
1019 : op_(OpBits::decode(key)), 1013 left_state_(LeftStateField::decode(state)),
1020 mode_(ModeBits::decode(key)), 1014 right_state_(fixed_right_arg_.has_value
1021 platform_specific_bit_(PlatformSpecificBits::decode(key)), 1015 ? ((fixed_right_arg_.value <= Smi::kMaxValue) ? SMI : INT32)
1022 left_type_(left_type), 1016 : RightStateField::decode(state)),
1023 right_type_(right_type), 1017 result_state_(ResultStateField::decode(state)) {
1024 result_type_(result_type), 1018 // We don't deserialize the SSE2 Field, since this is only used to be able
1025 encoded_right_arg_(fixed_right_arg.has_value, 1019 // to include SSE2 as well as non-SSE2 versions in the snapshot. For code
1026 encode_arg_value(fixed_right_arg.value)) { } 1020 // generation we always want it to reflect the current state.
1027 1021 ASSERT(!fixed_right_arg_.has_value ||
1028 static void decode_types_from_minor_key(int minor_key, 1022 can_encode_arg_value(fixed_right_arg_.value));
1029 BinaryOpIC::TypeInfo* left_type,
1030 BinaryOpIC::TypeInfo* right_type,
1031 BinaryOpIC::TypeInfo* result_type) {
1032 *left_type =
1033 static_cast<BinaryOpIC::TypeInfo>(LeftTypeBits::decode(minor_key));
1034 *right_type =
1035 static_cast<BinaryOpIC::TypeInfo>(RightTypeBits::decode(minor_key));
1036 *result_type =
1037 static_cast<BinaryOpIC::TypeInfo>(ResultTypeBits::decode(minor_key));
1038 } 1023 }
1039 1024
1040 static Token::Value decode_op_from_minor_key(int minor_key) { 1025 static const int FIRST_TOKEN = Token::BIT_OR;
1041 return static_cast<Token::Value>(OpBits::decode(minor_key)); 1026 static const int LAST_TOKEN = Token::MOD;
1027
1028 static void GenerateAheadOfTime(Isolate* isolate);
1029 virtual void InitializeInterfaceDescriptor(
1030 Isolate* isolate, CodeStubInterfaceDescriptor* descriptor);
1031 static void InitializeForIsolate(Isolate* isolate) {
1032 BinaryOpStub binopStub(UNINITIALIZED);
1033 binopStub.InitializeInterfaceDescriptor(
1034 isolate, isolate->code_stub_interface_descriptor(CodeStub::BinaryOp));
1042 } 1035 }
1043 1036
1044 static Maybe<int> decode_fixed_right_arg_from_minor_key(int minor_key) { 1037 virtual Code::Kind GetCodeKind() const { return Code::BINARY_OP_IC; }
1045 return Maybe<int>( 1038 virtual InlineCacheState GetICState() {
1046 HasFixedRightArgBits::decode(minor_key), 1039 if (Max(left_state_, right_state_) == NONE) {
1047 decode_arg_value(FixedRightArgValueBits::decode(minor_key))); 1040 return ::v8::internal::UNINITIALIZED;
1041 }
1042 if (Max(left_state_, right_state_) == GENERIC) return MEGAMORPHIC;
1043 return MONOMORPHIC;
1048 } 1044 }
1049 1045
1050 int fixed_right_arg_value() const { 1046 virtual Code::ExtraICState GetExtraICState() {
1051 return decode_arg_value(encoded_right_arg_.value); 1047 bool sse_field = Max(result_state_, Max(left_state_, right_state_)) > SMI &&
1048 CpuFeatures::IsSafeForSnapshot(SSE2);
1049
1050 return OpBits::encode(encode_token(op_))
1051 | LeftStateField::encode(left_state_)
1052 | RightStateField::encode(fixed_right_arg_.has_value
1053 ? NONE : right_state_)
1054 | ResultStateField::encode(result_state_)
1055 | HasFixedRightArgBits::encode(fixed_right_arg_.has_value)
1056 | FixedRightArgValueBits::encode(fixed_right_arg_.has_value
1057 ? encode_arg_value(
1058 fixed_right_arg_.value)
1059 : 0)
1060 | SSE2Field::encode(sse_field)
1061 | OverwriteModeField::encode(mode_);
1052 } 1062 }
1053 1063
1054 static bool can_encode_arg_value(int32_t value) { 1064 bool CanReuseDoubleBox() {
1055 return value > 0 && 1065 return result_state_ <= NUMBER && result_state_ > SMI &&
1056 IsPowerOf2(value) && 1066 ((left_state_ > SMI && left_state_ <= NUMBER &&
1057 FixedRightArgValueBits::is_valid(WhichPowerOf2(value)); 1067 mode_ == OVERWRITE_LEFT) ||
1068 (right_state_ > SMI && right_state_ <= NUMBER &&
1069 mode_ == OVERWRITE_RIGHT));
1058 } 1070 }
1059 1071
1060 enum SmiCodeGenerateHeapNumberResults { 1072 bool HasSideEffects(Isolate* isolate) const {
1061 ALLOW_HEAPNUMBER_RESULTS, 1073 Handle<Type> left = GetLeftType(isolate);
1062 NO_HEAPNUMBER_RESULTS 1074 Handle<Type> right = GetRightType(isolate);
1063 }; 1075 return left->Maybe(Type::Receiver()) || right->Maybe(Type::Receiver());
1076 }
1077
1078 virtual Handle<Code> GenerateCode(Isolate* isolate);
1079
1080 Maybe<Handle<Object> > Result(Handle<Object> left,
1081 Handle<Object> right,
1082 Isolate* isolate);
1083
1084 Token::Value operation() const { return op_; }
1085 OverwriteMode mode() const { return mode_; }
1086 Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
1087
1088 Handle<Type> GetLeftType(Isolate* isolate) const;
1089 Handle<Type> GetRightType(Isolate* isolate) const;
1090 Handle<Type> GetResultType(Isolate* isolate) const;
1091
1092 void UpdateStatus(Handle<Object> left,
1093 Handle<Object> right,
1094 Maybe<Handle<Object> > result);
1095
1096 void PrintState(StringStream* stream);
1064 1097
1065 private: 1098 private:
1099 explicit BinaryOpStub(InitializationState state) : HydrogenCodeStub(state),
1100 op_(Token::ADD),
1101 mode_(NO_OVERWRITE) {
1102 Initialize();
1103 }
1104 void Initialize();
1105
1106 enum State { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
1107
1108 // We truncate the last bit of the token.
1109 STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 5));
1110 class LeftStateField: public BitField<State, 0, 3> {};
1111 // When fixed right arg is set, we don't need to store the right state.
1112 // Thus the two fields can overlap.
1113 class HasFixedRightArgBits: public BitField<bool, 4, 1> {};
1114 class FixedRightArgValueBits: public BitField<int, 5, 4> {};
1115 class RightStateField: public BitField<State, 5, 3> {};
1116 class ResultStateField: public BitField<State, 9, 3> {};
1117 class SSE2Field: public BitField<bool, 12, 1> {};
1118 class OverwriteModeField: public BitField<OverwriteMode, 13, 2> {};
1119 class OpBits: public BitField<int, 15, 5> {};
1120
1121 virtual CodeStub::Major MajorKey() { return BinaryOp; }
1122 virtual int NotMissMinorKey() { return GetExtraICState(); }
1123
1124 static Handle<Type> StateToType(State state,
1125 Isolate* isolate);
1126
1127 static void Generate(Token::Value op,
1128 State left,
1129 int right,
1130 State result,
1131 OverwriteMode mode,
1132 Isolate* isolate);
1133
1134 static void Generate(Token::Value op,
1135 State left,
1136 State right,
1137 State result,
1138 OverwriteMode mode,
1139 Isolate* isolate);
1140
1141 void UpdateStatus(Handle<Object> object,
1142 State* state);
1143
1144 bool can_encode_arg_value(int32_t value) const;
1145 int encode_arg_value(int32_t value) const;
1146 int32_t decode_arg_value(int value) const;
1147 int encode_token(Token::Value op) const;
1148 Token::Value decode_token(int op) const;
1149
1150 bool has_int_result() const {
1151 return op_ == Token::BIT_XOR || op_ == Token::BIT_AND ||
1152 op_ == Token::BIT_OR || op_ == Token::SAR || op_ == Token::SHL;
1153 }
1154
1155 const char* StateToName(State state);
1156
1157 void PrintBaseName(StringStream* stream);
1158
1066 Token::Value op_; 1159 Token::Value op_;
1067 OverwriteMode mode_; 1160 OverwriteMode mode_;
1068 bool platform_specific_bit_; // Indicates SSE3 on IA32.
1069 1161
1070 // Operand type information determined at runtime. 1162 Maybe<int> fixed_right_arg_;
1071 BinaryOpIC::TypeInfo left_type_; 1163 State left_state_;
1072 BinaryOpIC::TypeInfo right_type_; 1164 State right_state_;
1073 BinaryOpIC::TypeInfo result_type_; 1165 State result_state_;
1074
1075 Maybe<int> encoded_right_arg_;
1076
1077 static int encode_arg_value(int32_t value) {
1078 ASSERT(can_encode_arg_value(value));
1079 return WhichPowerOf2(value);
1080 }
1081
1082 static int32_t decode_arg_value(int value) {
1083 return 1 << value;
1084 }
1085
1086 virtual void PrintName(StringStream* stream);
1087
1088 // Minor key encoding in all 25 bits FFFFFHTTTRRRLLLPOOOOOOOMM.
1089 // Note: We actually do not need 7 bits for the operation, just 4 bits to
1090 // encode ADD, SUB, MUL, DIV, MOD, BIT_OR, BIT_AND, BIT_XOR, SAR, SHL, SHR.
1091 class ModeBits: public BitField<OverwriteMode, 0, 2> {};
1092 class OpBits: public BitField<Token::Value, 2, 7> {};
1093 class PlatformSpecificBits: public BitField<bool, 9, 1> {};
1094 class LeftTypeBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {};
1095 class RightTypeBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {};
1096 class ResultTypeBits: public BitField<BinaryOpIC::TypeInfo, 16, 3> {};
1097 class HasFixedRightArgBits: public BitField<bool, 19, 1> {};
1098 class FixedRightArgValueBits: public BitField<int, 20, 5> {};
1099
1100 Major MajorKey() { return BinaryOp; }
1101 int MinorKey() {
1102 return OpBits::encode(op_)
1103 | ModeBits::encode(mode_)
1104 | PlatformSpecificBits::encode(platform_specific_bit_)
1105 | LeftTypeBits::encode(left_type_)
1106 | RightTypeBits::encode(right_type_)
1107 | ResultTypeBits::encode(result_type_)
1108 | HasFixedRightArgBits::encode(encoded_right_arg_.has_value)
1109 | FixedRightArgValueBits::encode(encoded_right_arg_.value);
1110 }
1111
1112
1113 // Platform-independent implementation.
1114 void Generate(MacroAssembler* masm);
1115 void GenerateCallRuntime(MacroAssembler* masm);
1116
1117 // Platform-independent signature, platform-specific implementation.
1118 void Initialize();
1119 void GenerateAddStrings(MacroAssembler* masm);
1120 void GenerateBothStringStub(MacroAssembler* masm);
1121 void GenerateGeneric(MacroAssembler* masm);
1122 void GenerateGenericStub(MacroAssembler* masm);
1123 void GenerateNumberStub(MacroAssembler* masm);
1124 void GenerateInt32Stub(MacroAssembler* masm);
1125 void GenerateLoadArguments(MacroAssembler* masm);
1126 void GenerateOddballStub(MacroAssembler* masm);
1127 void GenerateRegisterArgsPush(MacroAssembler* masm);
1128 void GenerateReturn(MacroAssembler* masm);
1129 void GenerateSmiStub(MacroAssembler* masm);
1130 void GenerateStringStub(MacroAssembler* masm);
1131 void GenerateTypeTransition(MacroAssembler* masm);
1132 void GenerateTypeTransitionWithSavedArgs(MacroAssembler* masm);
1133 void GenerateUninitializedStub(MacroAssembler* masm);
1134
1135 // Entirely platform-specific methods are defined as static helper
1136 // functions in the <arch>/code-stubs-<arch>.cc files.
1137
1138 virtual Code::Kind GetCodeKind() const { return Code::BINARY_OP_IC; }
1139
1140 virtual InlineCacheState GetICState() {
1141 return BinaryOpIC::ToState(Max(left_type_, right_type_));
1142 }
1143
1144 virtual void FinishCode(Handle<Code> code) {
1145 code->set_stub_info(MinorKey());
1146 }
1147
1148 friend class CodeGenerator;
1149 }; 1166 };
1150 1167
1151 1168
1152 class ICCompareStub: public PlatformCodeStub { 1169 class ICCompareStub: public PlatformCodeStub {
1153 public: 1170 public:
1154 ICCompareStub(Token::Value op, 1171 ICCompareStub(Token::Value op,
1155 CompareIC::State left, 1172 CompareIC::State left,
1156 CompareIC::State right, 1173 CompareIC::State right,
1157 CompareIC::State handler) 1174 CompareIC::State handler)
1158 : op_(op), 1175 : op_(op),
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
1711 public: 1728 public:
1712 DoubleToIStub(Register source, 1729 DoubleToIStub(Register source,
1713 Register destination, 1730 Register destination,
1714 int offset, 1731 int offset,
1715 bool is_truncating, 1732 bool is_truncating,
1716 bool skip_fastpath = false) : bit_field_(0) { 1733 bool skip_fastpath = false) : bit_field_(0) {
1717 bit_field_ = SourceRegisterBits::encode(source.code_) | 1734 bit_field_ = SourceRegisterBits::encode(source.code_) |
1718 DestinationRegisterBits::encode(destination.code_) | 1735 DestinationRegisterBits::encode(destination.code_) |
1719 OffsetBits::encode(offset) | 1736 OffsetBits::encode(offset) |
1720 IsTruncatingBits::encode(is_truncating) | 1737 IsTruncatingBits::encode(is_truncating) |
1721 SkipFastPathBits::encode(skip_fastpath); 1738 SkipFastPathBits::encode(skip_fastpath) |
1739 SSEBits::encode(CpuFeatures::IsSafeForSnapshot(SSE2) ?
1740 CpuFeatures::IsSafeForSnapshot(SSE3) ? 2 : 1 : 0);
1722 } 1741 }
1723 1742
1724 Register source() { 1743 Register source() {
1725 Register result = { SourceRegisterBits::decode(bit_field_) }; 1744 Register result = { SourceRegisterBits::decode(bit_field_) };
1726 return result; 1745 return result;
1727 } 1746 }
1728 1747
1729 Register destination() { 1748 Register destination() {
1730 Register result = { DestinationRegisterBits::decode(bit_field_) }; 1749 Register result = { DestinationRegisterBits::decode(bit_field_) };
1731 return result; 1750 return result;
(...skipping 22 matching lines...) Expand all
1754 public BitField<int, 0, kBitsPerRegisterNumber> {}; // NOLINT 1773 public BitField<int, 0, kBitsPerRegisterNumber> {}; // NOLINT
1755 class DestinationRegisterBits: 1774 class DestinationRegisterBits:
1756 public BitField<int, kBitsPerRegisterNumber, 1775 public BitField<int, kBitsPerRegisterNumber,
1757 kBitsPerRegisterNumber> {}; // NOLINT 1776 kBitsPerRegisterNumber> {}; // NOLINT
1758 class IsTruncatingBits: 1777 class IsTruncatingBits:
1759 public BitField<bool, 2 * kBitsPerRegisterNumber, 1> {}; // NOLINT 1778 public BitField<bool, 2 * kBitsPerRegisterNumber, 1> {}; // NOLINT
1760 class OffsetBits: 1779 class OffsetBits:
1761 public BitField<int, 2 * kBitsPerRegisterNumber + 1, 3> {}; // NOLINT 1780 public BitField<int, 2 * kBitsPerRegisterNumber + 1, 3> {}; // NOLINT
1762 class SkipFastPathBits: 1781 class SkipFastPathBits:
1763 public BitField<int, 2 * kBitsPerRegisterNumber + 4, 1> {}; // NOLINT 1782 public BitField<int, 2 * kBitsPerRegisterNumber + 4, 1> {}; // NOLINT
1783 class SSEBits:
1784 public BitField<int, 2 * kBitsPerRegisterNumber + 5, 2> {}; // NOLINT
1764 1785
1765 Major MajorKey() { return DoubleToI; } 1786 Major MajorKey() { return DoubleToI; }
1766 int MinorKey() { return bit_field_; } 1787 int MinorKey() { return bit_field_; }
1767 1788
1768 int bit_field_; 1789 int bit_field_;
1769 1790
1770 DISALLOW_COPY_AND_ASSIGN(DoubleToIStub); 1791 DISALLOW_COPY_AND_ASSIGN(DoubleToIStub);
1771 }; 1792 };
1772 1793
1773 1794
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
2320 int MinorKey() { return 0; } 2341 int MinorKey() { return 0; }
2321 2342
2322 void Generate(MacroAssembler* masm); 2343 void Generate(MacroAssembler* masm);
2323 2344
2324 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); 2345 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub);
2325 }; 2346 };
2326 2347
2327 } } // namespace v8::internal 2348 } } // namespace v8::internal
2328 2349
2329 #endif // V8_CODE_STUBS_H_ 2350 #endif // V8_CODE_STUBS_H_
OLDNEW
« no previous file with comments | « src/ast.h ('k') | src/code-stubs.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698