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

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

Issue 97543002: Refactor BinaryOpIC to be able to use different stubs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 7 years 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
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 23 matching lines...) Expand all
34 #include "globals.h" 34 #include "globals.h"
35 #include "macro-assembler.h" 35 #include "macro-assembler.h"
36 36
37 namespace v8 { 37 namespace v8 {
38 namespace internal { 38 namespace internal {
39 39
40 // List of code stubs used on all platforms. 40 // List of code stubs used on all platforms.
41 #define CODE_STUB_LIST_ALL_PLATFORMS(V) \ 41 #define CODE_STUB_LIST_ALL_PLATFORMS(V) \
42 V(CallFunction) \ 42 V(CallFunction) \
43 V(CallConstruct) \ 43 V(CallConstruct) \
44 V(BinaryOp) \ 44 V(BinaryOpIC) \
45 V(StringAdd) \ 45 V(StringAdd) \
46 V(NewStringAdd) \ 46 V(NewStringAdd) \
47 V(SubString) \ 47 V(SubString) \
48 V(StringCompare) \ 48 V(StringCompare) \
49 V(Compare) \ 49 V(Compare) \
50 V(CompareIC) \ 50 V(CompareIC) \
51 V(CompareNilIC) \ 51 V(CompareNilIC) \
52 V(MathPow) \ 52 V(MathPow) \
53 V(StringLength) \ 53 V(StringLength) \
54 V(FunctionPrototype) \ 54 V(FunctionPrototype) \
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 #else 119 #else
120 #define CODE_STUB_LIST_MIPS(V) 120 #define CODE_STUB_LIST_MIPS(V)
121 #endif 121 #endif
122 122
123 // Combined list of code stubs. 123 // Combined list of code stubs.
124 #define CODE_STUB_LIST(V) \ 124 #define CODE_STUB_LIST(V) \
125 CODE_STUB_LIST_ALL_PLATFORMS(V) \ 125 CODE_STUB_LIST_ALL_PLATFORMS(V) \
126 CODE_STUB_LIST_ARM(V) \ 126 CODE_STUB_LIST_ARM(V) \
127 CODE_STUB_LIST_MIPS(V) 127 CODE_STUB_LIST_MIPS(V)
128 128
129 // Mode to overwrite BinaryExpression values.
130 enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
131
132 // Stub is base classes of all stubs. 129 // Stub is base classes of all stubs.
133 class CodeStub BASE_EMBEDDED { 130 class CodeStub BASE_EMBEDDED {
134 public: 131 public:
135 enum Major { 132 enum Major {
136 #define DEF_ENUM(name) name, 133 #define DEF_ENUM(name) name,
137 CODE_STUB_LIST(DEF_ENUM) 134 CODE_STUB_LIST(DEF_ENUM)
138 #undef DEF_ENUM 135 #undef DEF_ENUM
139 NoCache, // marker for stubs that do custom caching 136 NoCache, // marker for stubs that do custom caching
140 NUMBER_OF_IDS 137 NUMBER_OF_IDS
141 }; 138 };
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 STATIC_ASSERT(CallICBase::Contextual::kSize == ContextualBits::kSize); 1051 STATIC_ASSERT(CallICBase::Contextual::kSize == ContextualBits::kSize);
1055 class HoleyBits: public BitField<bool, 1, 1> {}; 1052 class HoleyBits: public BitField<bool, 1, 1> {};
1056 STATIC_ASSERT(Code::kArgumentsBits <= kStubMinorKeyBits - 2); 1053 STATIC_ASSERT(Code::kArgumentsBits <= kStubMinorKeyBits - 2);
1057 class ArgcBits: public BitField<int, 2, Code::kArgumentsBits> {}; 1054 class ArgcBits: public BitField<int, 2, Code::kArgumentsBits> {};
1058 virtual CodeStub::Major MajorKey() { return KeyedArrayCall; } 1055 virtual CodeStub::Major MajorKey() { return KeyedArrayCall; }
1059 int bit_field_; 1056 int bit_field_;
1060 int argc_; 1057 int argc_;
1061 }; 1058 };
1062 1059
1063 1060
1064 class BinaryOpStub: public HydrogenCodeStub { 1061 class BinaryOpICStub V8_FINAL : public HydrogenCodeStub {
1065 public: 1062 public:
1066 BinaryOpStub(Token::Value op, OverwriteMode mode) 1063 BinaryOpICStub(Token::Value op, OverwriteMode mode)
1067 : HydrogenCodeStub(UNINITIALIZED), op_(op), mode_(mode) { 1064 : HydrogenCodeStub(UNINITIALIZED), state_(op, mode) {}
1068 ASSERT(op <= LAST_TOKEN && op >= FIRST_TOKEN); 1065
1069 Initialize(); 1066 explicit BinaryOpICStub(const BinaryOpIC::State& state) : state_(state) {}
1067
1068 static void GenerateAheadOfTime(Isolate* isolate);
1069
1070 virtual void InitializeInterfaceDescriptor(
1071 Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
1072
1073 static void InstallDescriptors(Isolate* isolate);
1074
1075 virtual Code::Kind GetCodeKind() const V8_OVERRIDE {
1076 return Code::BINARY_OP_IC;
1070 } 1077 }
1071 1078
1072 explicit BinaryOpStub(ExtraICState state) 1079 virtual InlineCacheState GetICState() V8_OVERRIDE {
1073 : op_(decode_token(OpBits::decode(state))), 1080 return state_.GetICState();
1074 mode_(OverwriteModeField::decode(state)),
1075 fixed_right_arg_(
1076 Maybe<int>(HasFixedRightArgBits::decode(state),
1077 decode_arg_value(FixedRightArgValueBits::decode(state)))),
1078 left_state_(LeftStateField::decode(state)),
1079 right_state_(fixed_right_arg_.has_value
1080 ? ((fixed_right_arg_.value <= Smi::kMaxValue) ? SMI : INT32)
1081 : RightStateField::decode(state)),
1082 result_state_(ResultStateField::decode(state)) {
1083 // We don't deserialize the SSE2 Field, since this is only used to be able
1084 // to include SSE2 as well as non-SSE2 versions in the snapshot. For code
1085 // generation we always want it to reflect the current state.
1086 ASSERT(!fixed_right_arg_.has_value ||
1087 can_encode_arg_value(fixed_right_arg_.value));
1088 } 1081 }
1089 1082
1090 static const int FIRST_TOKEN = Token::BIT_OR; 1083 virtual ExtraICState GetExtraICState() V8_OVERRIDE {
1091 static const int LAST_TOKEN = Token::MOD; 1084 return state_.GetExtraICState();
1092
1093 static void GenerateAheadOfTime(Isolate* isolate);
1094 virtual void InitializeInterfaceDescriptor(
1095 Isolate* isolate, CodeStubInterfaceDescriptor* descriptor);
1096 static void InitializeForIsolate(Isolate* isolate) {
1097 BinaryOpStub binopStub(UNINITIALIZED);
1098 binopStub.InitializeInterfaceDescriptor(
1099 isolate, isolate->code_stub_interface_descriptor(CodeStub::BinaryOp));
1100 }
1101
1102 virtual Code::Kind GetCodeKind() const { return Code::BINARY_OP_IC; }
1103 virtual InlineCacheState GetICState() {
1104 if (Max(left_state_, right_state_) == NONE) {
1105 return ::v8::internal::UNINITIALIZED;
1106 }
1107 if (Max(left_state_, right_state_) == GENERIC) return MEGAMORPHIC;
1108 return MONOMORPHIC;
1109 } 1085 }
1110 1086
1111 virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE { 1087 virtual void VerifyPlatformFeatures(Isolate* isolate) V8_OVERRIDE {
1112 ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2)); 1088 ASSERT(CpuFeatures::VerifyCrossCompiling(SSE2));
1113 } 1089 }
1114 1090
1115 virtual ExtraICState GetExtraICState() { 1091 virtual Handle<Code> GenerateCode(Isolate* isolate) V8_OVERRIDE;
1116 bool sse_field = Max(result_state_, Max(left_state_, right_state_)) > SMI &&
1117 CpuFeatures::IsSafeForSnapshot(SSE2);
1118 1092
1119 return OpBits::encode(encode_token(op_)) 1093 const BinaryOpIC::State& state() const { return state_; }
1120 | LeftStateField::encode(left_state_)
1121 | RightStateField::encode(fixed_right_arg_.has_value
1122 ? NONE : right_state_)
1123 | ResultStateField::encode(result_state_)
1124 | HasFixedRightArgBits::encode(fixed_right_arg_.has_value)
1125 | FixedRightArgValueBits::encode(fixed_right_arg_.has_value
1126 ? encode_arg_value(
1127 fixed_right_arg_.value)
1128 : 0)
1129 | SSE2Field::encode(sse_field)
1130 | OverwriteModeField::encode(mode_);
1131 }
1132 1094
1133 bool CanReuseDoubleBox() { 1095 virtual void PrintState(StringStream* stream) V8_OVERRIDE;
1134 return result_state_ <= NUMBER && result_state_ > SMI &&
1135 ((left_state_ > SMI && left_state_ <= NUMBER &&
1136 mode_ == OVERWRITE_LEFT) ||
1137 (right_state_ > SMI && right_state_ <= NUMBER &&
1138 mode_ == OVERWRITE_RIGHT));
1139 }
1140 1096
1141 bool HasSideEffects(Isolate* isolate) const { 1097 // Parameters accessed via CodeStubGraphBuilder::GetParameter()
1142 Handle<Type> left = GetLeftType(isolate); 1098 static const int kLeft = 0;
1143 Handle<Type> right = GetRightType(isolate); 1099 static const int kRight = 1;
1144 return left->Maybe(Type::Receiver()) || right->Maybe(Type::Receiver());
1145 }
1146
1147 virtual Handle<Code> GenerateCode(Isolate* isolate);
1148
1149 Maybe<Handle<Object> > Result(Handle<Object> left,
1150 Handle<Object> right,
1151 Isolate* isolate);
1152
1153 Token::Value operation() const { return op_; }
1154 OverwriteMode mode() const { return mode_; }
1155 Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
1156
1157 Handle<Type> GetLeftType(Isolate* isolate) const;
1158 Handle<Type> GetRightType(Isolate* isolate) const;
1159 Handle<Type> GetResultType(Isolate* isolate) const;
1160
1161 void UpdateStatus(Handle<Object> left,
1162 Handle<Object> right,
1163 Maybe<Handle<Object> > result);
1164
1165 void PrintState(StringStream* stream);
1166 1100
1167 private: 1101 private:
1168 explicit BinaryOpStub(InitializationState state) : HydrogenCodeStub(state), 1102 static void GenerateAheadOfTime(Isolate* isolate,
1169 op_(Token::ADD), 1103 const BinaryOpIC::State& state);
1170 mode_(NO_OVERWRITE) {
1171 Initialize();
1172 }
1173 void Initialize();
1174 1104
1175 enum State { NONE, SMI, INT32, NUMBER, STRING, GENERIC }; 1105 virtual Major MajorKey() V8_OVERRIDE { return BinaryOpIC; }
1106 virtual int NotMissMinorKey() V8_OVERRIDE { return GetExtraICState(); }
1176 1107
1177 // We truncate the last bit of the token. 1108 BinaryOpIC::State state_;
1178 STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 5));
1179 class LeftStateField: public BitField<State, 0, 3> {};
1180 // When fixed right arg is set, we don't need to store the right state.
1181 // Thus the two fields can overlap.
1182 class HasFixedRightArgBits: public BitField<bool, 4, 1> {};
1183 class FixedRightArgValueBits: public BitField<int, 5, 4> {};
1184 class RightStateField: public BitField<State, 5, 3> {};
1185 class ResultStateField: public BitField<State, 9, 3> {};
1186 class SSE2Field: public BitField<bool, 12, 1> {};
1187 class OverwriteModeField: public BitField<OverwriteMode, 13, 2> {};
1188 class OpBits: public BitField<int, 15, 5> {};
1189 1109
1190 virtual CodeStub::Major MajorKey() { return BinaryOp; } 1110 DISALLOW_COPY_AND_ASSIGN(BinaryOpICStub);
1191 virtual int NotMissMinorKey() { return GetExtraICState(); }
1192
1193 static Handle<Type> StateToType(State state,
1194 Isolate* isolate);
1195
1196 static void Generate(Token::Value op,
1197 State left,
1198 int right,
1199 State result,
1200 OverwriteMode mode,
1201 Isolate* isolate);
1202
1203 static void Generate(Token::Value op,
1204 State left,
1205 State right,
1206 State result,
1207 OverwriteMode mode,
1208 Isolate* isolate);
1209
1210 void UpdateStatus(Handle<Object> object,
1211 State* state);
1212
1213 bool can_encode_arg_value(int32_t value) const;
1214 int encode_arg_value(int32_t value) const;
1215 int32_t decode_arg_value(int value) const;
1216 int encode_token(Token::Value op) const;
1217 Token::Value decode_token(int op) const;
1218
1219 bool has_int_result() const {
1220 return op_ == Token::BIT_XOR || op_ == Token::BIT_AND ||
1221 op_ == Token::BIT_OR || op_ == Token::SAR || op_ == Token::SHL;
1222 }
1223
1224 const char* StateToName(State state);
1225
1226 void PrintBaseName(StringStream* stream);
1227
1228 Token::Value op_;
1229 OverwriteMode mode_;
1230
1231 Maybe<int> fixed_right_arg_;
1232 State left_state_;
1233 State right_state_;
1234 State result_state_;
1235 }; 1111 };
1236 1112
1237 1113
1238 // TODO(bmeurer): Rename to StringAddStub once we dropped the old StringAddStub. 1114 // TODO(bmeurer): Rename to StringAddStub once we dropped the old StringAddStub.
1239 class NewStringAddStub V8_FINAL : public HydrogenCodeStub { 1115 class NewStringAddStub V8_FINAL : public HydrogenCodeStub {
1240 public: 1116 public:
1241 NewStringAddStub(StringAddFlags flags, PretenureFlag pretenure_flag) 1117 NewStringAddStub(StringAddFlags flags, PretenureFlag pretenure_flag)
1242 : bit_field_(StringAddFlagsBits::encode(flags) | 1118 : bit_field_(StringAddFlagsBits::encode(flags) |
1243 PretenureFlagBits::encode(pretenure_flag)) {} 1119 PretenureFlagBits::encode(pretenure_flag)) {}
1244 1120
(...skipping 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after
2471 int MinorKey() { return 0; } 2347 int MinorKey() { return 0; }
2472 2348
2473 void Generate(MacroAssembler* masm); 2349 void Generate(MacroAssembler* masm);
2474 2350
2475 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); 2351 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub);
2476 }; 2352 };
2477 2353
2478 } } // namespace v8::internal 2354 } } // namespace v8::internal
2479 2355
2480 #endif // V8_CODE_STUBS_H_ 2356 #endif // V8_CODE_STUBS_H_
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.cc ('k') | src/code-stubs.cc » ('j') | src/log.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698