OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_CODE_STUBS_H_ | 5 #ifndef V8_CODE_STUBS_H_ |
6 #define V8_CODE_STUBS_H_ | 6 #define V8_CODE_STUBS_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
9 #include "src/assembler.h" | 9 #include "src/assembler.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 } | 197 } |
198 | 198 |
199 friend OStream& operator<<(OStream& os, const CodeStub& s) { | 199 friend OStream& operator<<(OStream& os, const CodeStub& s) { |
200 s.PrintName(os); | 200 s.PrintName(os); |
201 return os; | 201 return os; |
202 } | 202 } |
203 | 203 |
204 Isolate* isolate() const { return isolate_; } | 204 Isolate* isolate() const { return isolate_; } |
205 | 205 |
206 protected: | 206 protected: |
| 207 explicit CodeStub(uint32_t key) : minor_key_(MinorKeyFromKey(key)) {} |
| 208 |
207 // Generates the assembler code for the stub. | 209 // Generates the assembler code for the stub. |
208 virtual Handle<Code> GenerateCode() = 0; | 210 virtual Handle<Code> GenerateCode() = 0; |
209 | 211 |
210 // Returns whether the code generated for this stub needs to be allocated as | 212 // Returns whether the code generated for this stub needs to be allocated as |
211 // a fixed (non-moveable) code object. | 213 // a fixed (non-moveable) code object. |
212 virtual bool NeedsImmovableCode() { return false; } | 214 virtual bool NeedsImmovableCode() { return false; } |
213 | 215 |
214 virtual void PrintName(OStream& os) const; // NOLINT | 216 virtual void PrintName(OStream& os) const; // NOLINT |
215 virtual void PrintBaseName(OStream& os) const; // NOLINT | 217 virtual void PrintBaseName(OStream& os) const; // NOLINT |
216 virtual void PrintState(OStream& os) const { ; } // NOLINT | 218 virtual void PrintState(OStream& os) const { ; } // NOLINT |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 explicit PlatformCodeStub(Isolate* isolate) : CodeStub(isolate) { } | 269 explicit PlatformCodeStub(Isolate* isolate) : CodeStub(isolate) { } |
268 | 270 |
269 // Retrieve the code for the stub. Generate the code if needed. | 271 // Retrieve the code for the stub. Generate the code if needed. |
270 virtual Handle<Code> GenerateCode() V8_OVERRIDE; | 272 virtual Handle<Code> GenerateCode() V8_OVERRIDE; |
271 | 273 |
272 virtual Code::Kind GetCodeKind() const { return Code::STUB; } | 274 virtual Code::Kind GetCodeKind() const { return Code::STUB; } |
273 | 275 |
274 protected: | 276 protected: |
275 // Generates the assembler code for the stub. | 277 // Generates the assembler code for the stub. |
276 virtual void Generate(MacroAssembler* masm) = 0; | 278 virtual void Generate(MacroAssembler* masm) = 0; |
| 279 |
| 280 explicit PlatformCodeStub(uint32_t key) : CodeStub(key) {} |
| 281 |
| 282 private: |
| 283 DISALLOW_COPY_AND_ASSIGN(PlatformCodeStub); |
277 }; | 284 }; |
278 | 285 |
279 | 286 |
280 enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; | 287 enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE }; |
281 enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS }; | 288 enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS }; |
282 | 289 |
283 | 290 |
284 class CodeStubInterfaceDescriptor { | 291 class CodeStubInterfaceDescriptor { |
285 public: | 292 public: |
286 CodeStubInterfaceDescriptor(); | 293 CodeStubInterfaceDescriptor(); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
409 } | 416 } |
410 | 417 |
411 virtual void InitializeInterfaceDescriptor( | 418 virtual void InitializeInterfaceDescriptor( |
412 CodeStubInterfaceDescriptor* descriptor) = 0; | 419 CodeStubInterfaceDescriptor* descriptor) = 0; |
413 | 420 |
414 // Retrieve the code for the stub. Generate the code if needed. | 421 // Retrieve the code for the stub. Generate the code if needed. |
415 virtual Handle<Code> GenerateCode() = 0; | 422 virtual Handle<Code> GenerateCode() = 0; |
416 | 423 |
417 bool IsUninitialized() const { return IsMissBits::decode(minor_key_); } | 424 bool IsUninitialized() const { return IsMissBits::decode(minor_key_); } |
418 | 425 |
419 // TODO(yangguo): we use this temporarily to construct the minor key. | |
420 // We want to remove NotMissMinorKey methods one by one and eventually | |
421 // remove HydrogenStub::MinorKey and turn CodeStub::MinorKey into a | |
422 // non-virtual method that directly returns minor_key_. | |
423 virtual int NotMissMinorKey() const { | |
424 return SubMinorKeyBits::decode(minor_key_); | |
425 } | |
426 | |
427 Handle<Code> GenerateLightweightMissCode(); | 426 Handle<Code> GenerateLightweightMissCode(); |
428 | 427 |
429 template<class StateType> | 428 template<class StateType> |
430 void TraceTransition(StateType from, StateType to); | 429 void TraceTransition(StateType from, StateType to); |
431 | 430 |
432 protected: | 431 protected: |
433 void set_sub_minor_key(uint32_t key) { | 432 void set_sub_minor_key(uint32_t key) { |
434 minor_key_ = SubMinorKeyBits::update(minor_key_, key); | 433 minor_key_ = SubMinorKeyBits::update(minor_key_, key); |
435 } | 434 } |
436 | 435 |
437 uint32_t sub_minor_key() const { return SubMinorKeyBits::decode(minor_key_); } | 436 uint32_t sub_minor_key() const { return SubMinorKeyBits::decode(minor_key_); } |
438 | 437 |
439 static const int kSubMinorKeyBits = kStubMinorKeyBits - 1; | 438 static const int kSubMinorKeyBits = kStubMinorKeyBits - 1; |
440 | 439 |
| 440 private: |
| 441 class IsMissBits : public BitField<bool, kSubMinorKeyBits, 1> {}; |
441 class SubMinorKeyBits : public BitField<int, 0, kSubMinorKeyBits> {}; | 442 class SubMinorKeyBits : public BitField<int, 0, kSubMinorKeyBits> {}; |
442 | 443 |
443 private: | 444 void GenerateLightweightMiss(MacroAssembler* masm); |
444 class IsMissBits : public BitField<bool, kSubMinorKeyBits, 1> {}; | |
445 | 445 |
446 void GenerateLightweightMiss(MacroAssembler* masm); | 446 DISALLOW_COPY_AND_ASSIGN(HydrogenCodeStub); |
447 virtual uint32_t MinorKey() const { | |
448 return IsMissBits::encode(IsUninitialized()) | | |
449 SubMinorKeyBits::encode(NotMissMinorKey()); | |
450 } | |
451 }; | 447 }; |
452 | 448 |
453 | 449 |
454 // Helper interface to prepare to/restore after making runtime calls. | 450 // Helper interface to prepare to/restore after making runtime calls. |
455 class RuntimeCallHelper { | 451 class RuntimeCallHelper { |
456 public: | 452 public: |
457 virtual ~RuntimeCallHelper() {} | 453 virtual ~RuntimeCallHelper() {} |
458 | 454 |
459 virtual void BeforeCall(MacroAssembler* masm) const = 0; | 455 virtual void BeforeCall(MacroAssembler* masm) const = 0; |
460 | 456 |
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 virtual Major MajorKey() const V8_OVERRIDE { return CallApiGetter; } | 1112 virtual Major MajorKey() const V8_OVERRIDE { return CallApiGetter; } |
1117 | 1113 |
1118 DISALLOW_COPY_AND_ASSIGN(CallApiGetterStub); | 1114 DISALLOW_COPY_AND_ASSIGN(CallApiGetterStub); |
1119 }; | 1115 }; |
1120 | 1116 |
1121 | 1117 |
1122 class BinaryOpICStub : public HydrogenCodeStub { | 1118 class BinaryOpICStub : public HydrogenCodeStub { |
1123 public: | 1119 public: |
1124 BinaryOpICStub(Isolate* isolate, Token::Value op, | 1120 BinaryOpICStub(Isolate* isolate, Token::Value op, |
1125 OverwriteMode mode = NO_OVERWRITE) | 1121 OverwriteMode mode = NO_OVERWRITE) |
1126 : HydrogenCodeStub(isolate, UNINITIALIZED), state_(isolate, op, mode) {} | 1122 : HydrogenCodeStub(isolate, UNINITIALIZED) { |
| 1123 BinaryOpIC::State state(isolate, op, mode); |
| 1124 set_sub_minor_key(state.GetExtraICState()); |
| 1125 } |
1127 | 1126 |
1128 explicit BinaryOpICStub(Isolate* isolate, const BinaryOpIC::State& state) | 1127 explicit BinaryOpICStub(Isolate* isolate, const BinaryOpIC::State& state) |
1129 : HydrogenCodeStub(isolate), state_(state) {} | 1128 : HydrogenCodeStub(isolate) { |
| 1129 set_sub_minor_key(state.GetExtraICState()); |
| 1130 } |
1130 | 1131 |
1131 static void GenerateAheadOfTime(Isolate* isolate); | 1132 static void GenerateAheadOfTime(Isolate* isolate); |
1132 | 1133 |
1133 virtual void InitializeInterfaceDescriptor( | 1134 virtual void InitializeInterfaceDescriptor( |
1134 CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; | 1135 CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; |
1135 | 1136 |
1136 static void InstallDescriptors(Isolate* isolate); | 1137 static void InstallDescriptors(Isolate* isolate); |
1137 | 1138 |
1138 virtual Code::Kind GetCodeKind() const V8_OVERRIDE { | 1139 virtual Code::Kind GetCodeKind() const V8_OVERRIDE { |
1139 return Code::BINARY_OP_IC; | 1140 return Code::BINARY_OP_IC; |
1140 } | 1141 } |
1141 | 1142 |
1142 virtual InlineCacheState GetICState() const V8_FINAL V8_OVERRIDE { | 1143 virtual InlineCacheState GetICState() const V8_FINAL V8_OVERRIDE { |
1143 return state_.GetICState(); | 1144 return state().GetICState(); |
1144 } | 1145 } |
1145 | 1146 |
1146 virtual ExtraICState GetExtraICState() const V8_FINAL V8_OVERRIDE { | 1147 virtual ExtraICState GetExtraICState() const V8_FINAL V8_OVERRIDE { |
1147 return state_.GetExtraICState(); | 1148 return static_cast<ExtraICState>(sub_minor_key()); |
1148 } | 1149 } |
1149 | 1150 |
1150 virtual Handle<Code> GenerateCode() V8_OVERRIDE; | 1151 virtual Handle<Code> GenerateCode() V8_OVERRIDE; |
1151 | 1152 |
1152 const BinaryOpIC::State& state() const { return state_; } | 1153 BinaryOpIC::State state() const { |
| 1154 return BinaryOpIC::State(isolate(), GetExtraICState()); |
| 1155 } |
1153 | 1156 |
1154 virtual void PrintState(OStream& os) const V8_FINAL V8_OVERRIDE; // NOLINT | 1157 virtual void PrintState(OStream& os) const V8_FINAL V8_OVERRIDE; // NOLINT |
1155 | 1158 |
1156 virtual Major MajorKey() const V8_OVERRIDE { return BinaryOpIC; } | |
1157 virtual int NotMissMinorKey() const V8_FINAL V8_OVERRIDE { | |
1158 return GetExtraICState(); | |
1159 } | |
1160 | |
1161 // Parameters accessed via CodeStubGraphBuilder::GetParameter() | 1159 // Parameters accessed via CodeStubGraphBuilder::GetParameter() |
1162 static const int kLeft = 0; | 1160 static const int kLeft = 0; |
1163 static const int kRight = 1; | 1161 static const int kRight = 1; |
1164 | 1162 |
1165 private: | 1163 private: |
| 1164 virtual Major MajorKey() const V8_OVERRIDE { return BinaryOpIC; } |
| 1165 |
1166 static void GenerateAheadOfTime(Isolate* isolate, | 1166 static void GenerateAheadOfTime(Isolate* isolate, |
1167 const BinaryOpIC::State& state); | 1167 const BinaryOpIC::State& state); |
1168 | 1168 |
1169 BinaryOpIC::State state_; | |
1170 | |
1171 DISALLOW_COPY_AND_ASSIGN(BinaryOpICStub); | 1169 DISALLOW_COPY_AND_ASSIGN(BinaryOpICStub); |
1172 }; | 1170 }; |
1173 | 1171 |
1174 | 1172 |
1175 // TODO(bmeurer): Merge this into the BinaryOpICStub once we have proper tail | 1173 // TODO(bmeurer): Merge this into the BinaryOpICStub once we have proper tail |
1176 // call support for stubs in Hydrogen. | 1174 // call support for stubs in Hydrogen. |
1177 class BinaryOpICWithAllocationSiteStub V8_FINAL : public PlatformCodeStub { | 1175 class BinaryOpICWithAllocationSiteStub V8_FINAL : public PlatformCodeStub { |
1178 public: | 1176 public: |
1179 BinaryOpICWithAllocationSiteStub(Isolate* isolate, | 1177 BinaryOpICWithAllocationSiteStub(Isolate* isolate, |
1180 const BinaryOpIC::State& state) | 1178 const BinaryOpIC::State& state) |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1302 class PretenureFlagBits: public BitField<PretenureFlag, 2, 1> {}; | 1300 class PretenureFlagBits: public BitField<PretenureFlag, 2, 1> {}; |
1303 | 1301 |
1304 virtual void PrintBaseName(OStream& os) const V8_OVERRIDE; // NOLINT | 1302 virtual void PrintBaseName(OStream& os) const V8_OVERRIDE; // NOLINT |
1305 | 1303 |
1306 DISALLOW_COPY_AND_ASSIGN(StringAddStub); | 1304 DISALLOW_COPY_AND_ASSIGN(StringAddStub); |
1307 }; | 1305 }; |
1308 | 1306 |
1309 | 1307 |
1310 class ICCompareStub: public PlatformCodeStub { | 1308 class ICCompareStub: public PlatformCodeStub { |
1311 public: | 1309 public: |
1312 ICCompareStub(Isolate* isolate, | 1310 ICCompareStub(Isolate* isolate, Token::Value op, CompareIC::State left, |
1313 Token::Value op, | 1311 CompareIC::State right, CompareIC::State state) |
1314 CompareIC::State left, | 1312 : PlatformCodeStub(isolate) { |
1315 CompareIC::State right, | |
1316 CompareIC::State handler) | |
1317 : PlatformCodeStub(isolate), | |
1318 op_(op), | |
1319 left_(left), | |
1320 right_(right), | |
1321 state_(handler) { | |
1322 DCHECK(Token::IsCompareOp(op)); | 1313 DCHECK(Token::IsCompareOp(op)); |
| 1314 minor_key_ = OpBits::encode(op - Token::EQ) | LeftStateBits::encode(left) | |
| 1315 RightStateBits::encode(right) | StateBits::encode(state); |
1323 } | 1316 } |
1324 | 1317 |
1325 virtual void Generate(MacroAssembler* masm); | 1318 virtual void Generate(MacroAssembler* masm); |
1326 | 1319 |
1327 void set_known_map(Handle<Map> map) { known_map_ = map; } | 1320 void set_known_map(Handle<Map> map) { known_map_ = map; } |
1328 | 1321 |
1329 static void DecodeKey(uint32_t stub_key, CompareIC::State* left_state, | 1322 explicit ICCompareStub(uint32_t stub_key) : PlatformCodeStub(stub_key) { |
1330 CompareIC::State* right_state, | 1323 DCHECK_EQ(MajorKeyFromKey(stub_key), MajorKey()); |
1331 CompareIC::State* handler_state, Token::Value* op); | 1324 } |
1332 | 1325 |
1333 virtual InlineCacheState GetICState() const; | 1326 virtual InlineCacheState GetICState() const; |
1334 | 1327 |
| 1328 Token::Value op() const { |
| 1329 return static_cast<Token::Value>(Token::EQ + OpBits::decode(minor_key_)); |
| 1330 } |
| 1331 |
| 1332 CompareIC::State left() const { return LeftStateBits::decode(minor_key_); } |
| 1333 CompareIC::State right() const { return RightStateBits::decode(minor_key_); } |
| 1334 CompareIC::State state() const { return StateBits::decode(minor_key_); } |
| 1335 |
1335 private: | 1336 private: |
1336 class OpField: public BitField<int, 0, 3> { }; | |
1337 class LeftStateField: public BitField<int, 3, 4> { }; | |
1338 class RightStateField: public BitField<int, 7, 4> { }; | |
1339 class HandlerStateField: public BitField<int, 11, 4> { }; | |
1340 | |
1341 virtual Major MajorKey() const V8_OVERRIDE { return CompareIC; } | 1337 virtual Major MajorKey() const V8_OVERRIDE { return CompareIC; } |
1342 virtual uint32_t MinorKey() const; | |
1343 | 1338 |
1344 virtual Code::Kind GetCodeKind() const { return Code::COMPARE_IC; } | 1339 virtual Code::Kind GetCodeKind() const { return Code::COMPARE_IC; } |
1345 | 1340 |
1346 void GenerateSmis(MacroAssembler* masm); | 1341 void GenerateSmis(MacroAssembler* masm); |
1347 void GenerateNumbers(MacroAssembler* masm); | 1342 void GenerateNumbers(MacroAssembler* masm); |
1348 void GenerateInternalizedStrings(MacroAssembler* masm); | 1343 void GenerateInternalizedStrings(MacroAssembler* masm); |
1349 void GenerateStrings(MacroAssembler* masm); | 1344 void GenerateStrings(MacroAssembler* masm); |
1350 void GenerateUniqueNames(MacroAssembler* masm); | 1345 void GenerateUniqueNames(MacroAssembler* masm); |
1351 void GenerateObjects(MacroAssembler* masm); | 1346 void GenerateObjects(MacroAssembler* masm); |
1352 void GenerateMiss(MacroAssembler* masm); | 1347 void GenerateMiss(MacroAssembler* masm); |
1353 void GenerateKnownObjects(MacroAssembler* masm); | 1348 void GenerateKnownObjects(MacroAssembler* masm); |
1354 void GenerateGeneric(MacroAssembler* masm); | 1349 void GenerateGeneric(MacroAssembler* masm); |
1355 | 1350 |
1356 bool strict() const { return op_ == Token::EQ_STRICT; } | 1351 bool strict() const { return op() == Token::EQ_STRICT; } |
1357 Condition GetCondition() const { return CompareIC::ComputeCondition(op_); } | 1352 Condition GetCondition() const { return CompareIC::ComputeCondition(op()); } |
1358 | 1353 |
1359 virtual void AddToSpecialCache(Handle<Code> new_object); | 1354 virtual void AddToSpecialCache(Handle<Code> new_object); |
1360 virtual bool FindCodeInSpecialCache(Code** code_out); | 1355 virtual bool FindCodeInSpecialCache(Code** code_out); |
1361 virtual bool UseSpecialCache() { return state_ == CompareIC::KNOWN_OBJECT; } | 1356 virtual bool UseSpecialCache() { return state() == CompareIC::KNOWN_OBJECT; } |
1362 | 1357 |
1363 Token::Value op_; | 1358 class OpBits : public BitField<int, 0, 3> {}; |
1364 CompareIC::State left_; | 1359 class LeftStateBits : public BitField<CompareIC::State, 3, 4> {}; |
1365 CompareIC::State right_; | 1360 class RightStateBits : public BitField<CompareIC::State, 7, 4> {}; |
1366 CompareIC::State state_; | 1361 class StateBits : public BitField<CompareIC::State, 11, 4> {}; |
| 1362 |
1367 Handle<Map> known_map_; | 1363 Handle<Map> known_map_; |
| 1364 |
| 1365 DISALLOW_COPY_AND_ASSIGN(ICCompareStub); |
1368 }; | 1366 }; |
1369 | 1367 |
1370 | 1368 |
1371 class CompareNilICStub : public HydrogenCodeStub { | 1369 class CompareNilICStub : public HydrogenCodeStub { |
1372 public: | 1370 public: |
1373 Type* GetType(Zone* zone, Handle<Map> map = Handle<Map>()); | 1371 Type* GetType(Zone* zone, Handle<Map> map = Handle<Map>()); |
1374 Type* GetInputType(Zone* zone, Handle<Map> map); | 1372 Type* GetInputType(Zone* zone, Handle<Map> map); |
1375 | 1373 |
1376 CompareNilICStub(Isolate* isolate, NilValue nil) | 1374 CompareNilICStub(Isolate* isolate, NilValue nil) : HydrogenCodeStub(isolate) { |
1377 : HydrogenCodeStub(isolate), nil_value_(nil) { } | 1375 set_sub_minor_key(NilValueBits::encode(nil)); |
| 1376 } |
1378 | 1377 |
1379 CompareNilICStub(Isolate* isolate, | 1378 CompareNilICStub(Isolate* isolate, ExtraICState ic_state, |
1380 ExtraICState ic_state, | |
1381 InitializationState init_state = INITIALIZED) | 1379 InitializationState init_state = INITIALIZED) |
1382 : HydrogenCodeStub(isolate, init_state), | 1380 : HydrogenCodeStub(isolate, init_state) { |
1383 nil_value_(NilValueField::decode(ic_state)), | 1381 set_sub_minor_key(ic_state); |
1384 state_(State(TypesField::decode(ic_state))) { | 1382 } |
1385 } | |
1386 | 1383 |
1387 static Handle<Code> GetUninitialized(Isolate* isolate, | 1384 static Handle<Code> GetUninitialized(Isolate* isolate, |
1388 NilValue nil) { | 1385 NilValue nil) { |
1389 return CompareNilICStub(isolate, nil, UNINITIALIZED).GetCode(); | 1386 return CompareNilICStub(isolate, nil, UNINITIALIZED).GetCode(); |
1390 } | 1387 } |
1391 | 1388 |
1392 virtual void InitializeInterfaceDescriptor( | 1389 virtual void InitializeInterfaceDescriptor( |
1393 CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; | 1390 CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; |
1394 | 1391 |
1395 static void InstallDescriptors(Isolate* isolate) { | 1392 static void InstallDescriptors(Isolate* isolate) { |
1396 CompareNilICStub compare_stub(isolate, kNullValue, UNINITIALIZED); | 1393 CompareNilICStub compare_stub(isolate, kNullValue, UNINITIALIZED); |
1397 compare_stub.InitializeInterfaceDescriptor( | 1394 compare_stub.InitializeInterfaceDescriptor( |
1398 isolate->code_stub_interface_descriptor(CodeStub::CompareNilIC)); | 1395 isolate->code_stub_interface_descriptor(CodeStub::CompareNilIC)); |
1399 } | 1396 } |
1400 | 1397 |
1401 virtual InlineCacheState GetICState() const { | 1398 virtual InlineCacheState GetICState() const { |
1402 if (state_.Contains(GENERIC)) { | 1399 State state = this->state(); |
| 1400 if (state.Contains(GENERIC)) { |
1403 return MEGAMORPHIC; | 1401 return MEGAMORPHIC; |
1404 } else if (state_.Contains(MONOMORPHIC_MAP)) { | 1402 } else if (state.Contains(MONOMORPHIC_MAP)) { |
1405 return MONOMORPHIC; | 1403 return MONOMORPHIC; |
1406 } else { | 1404 } else { |
1407 return PREMONOMORPHIC; | 1405 return PREMONOMORPHIC; |
1408 } | 1406 } |
1409 } | 1407 } |
1410 | 1408 |
1411 virtual Code::Kind GetCodeKind() const { return Code::COMPARE_NIL_IC; } | 1409 virtual Code::Kind GetCodeKind() const { return Code::COMPARE_NIL_IC; } |
1412 | 1410 |
1413 virtual Handle<Code> GenerateCode() V8_OVERRIDE; | 1411 virtual Handle<Code> GenerateCode() V8_OVERRIDE; |
1414 | 1412 |
1415 virtual ExtraICState GetExtraICState() const { | 1413 virtual ExtraICState GetExtraICState() const { return sub_minor_key(); } |
1416 return NilValueField::encode(nil_value_) | | |
1417 TypesField::encode(state_.ToIntegral()); | |
1418 } | |
1419 | 1414 |
1420 void UpdateStatus(Handle<Object> object); | 1415 void UpdateStatus(Handle<Object> object); |
1421 | 1416 |
1422 bool IsMonomorphic() const { return state_.Contains(MONOMORPHIC_MAP); } | 1417 bool IsMonomorphic() const { return state().Contains(MONOMORPHIC_MAP); } |
1423 NilValue GetNilValue() const { return nil_value_; } | 1418 |
1424 void ClearState() { state_.RemoveAll(); } | 1419 NilValue nil_value() const { return NilValueBits::decode(sub_minor_key()); } |
| 1420 |
| 1421 void ClearState() { |
| 1422 set_sub_minor_key(TypesBits::update(sub_minor_key(), 0)); |
| 1423 } |
1425 | 1424 |
1426 virtual void PrintState(OStream& os) const V8_OVERRIDE; // NOLINT | 1425 virtual void PrintState(OStream& os) const V8_OVERRIDE; // NOLINT |
1427 virtual void PrintBaseName(OStream& os) const V8_OVERRIDE; // NOLINT | 1426 virtual void PrintBaseName(OStream& os) const V8_OVERRIDE; // NOLINT |
1428 | 1427 |
1429 private: | 1428 private: |
1430 friend class CompareNilIC; | 1429 CompareNilICStub(Isolate* isolate, NilValue nil, |
| 1430 InitializationState init_state) |
| 1431 : HydrogenCodeStub(isolate, init_state) { |
| 1432 set_sub_minor_key(NilValueBits::encode(nil)); |
| 1433 } |
| 1434 |
| 1435 virtual Major MajorKey() const V8_OVERRIDE { return CompareNilIC; } |
1431 | 1436 |
1432 enum CompareNilType { | 1437 enum CompareNilType { |
1433 UNDEFINED, | 1438 UNDEFINED, |
1434 NULL_TYPE, | 1439 NULL_TYPE, |
1435 MONOMORPHIC_MAP, | 1440 MONOMORPHIC_MAP, |
1436 GENERIC, | 1441 GENERIC, |
1437 NUMBER_OF_TYPES | 1442 NUMBER_OF_TYPES |
1438 }; | 1443 }; |
1439 | 1444 |
1440 // At most 6 different types can be distinguished, because the Code object | 1445 // At most 6 different types can be distinguished, because the Code object |
1441 // only has room for a single byte to hold a set and there are two more | 1446 // only has room for a single byte to hold a set and there are two more |
1442 // boolean flags we need to store. :-P | 1447 // boolean flags we need to store. :-P |
1443 STATIC_ASSERT(NUMBER_OF_TYPES <= 6); | 1448 STATIC_ASSERT(NUMBER_OF_TYPES <= 6); |
1444 | 1449 |
1445 class State : public EnumSet<CompareNilType, byte> { | 1450 class State : public EnumSet<CompareNilType, byte> { |
1446 public: | 1451 public: |
1447 State() : EnumSet<CompareNilType, byte>(0) { } | 1452 State() : EnumSet<CompareNilType, byte>(0) { } |
1448 explicit State(byte bits) : EnumSet<CompareNilType, byte>(bits) { } | 1453 explicit State(byte bits) : EnumSet<CompareNilType, byte>(bits) { } |
1449 }; | 1454 }; |
1450 friend OStream& operator<<(OStream& os, const State& s); | 1455 friend OStream& operator<<(OStream& os, const State& s); |
1451 | 1456 |
1452 CompareNilICStub(Isolate* isolate, | 1457 State state() const { return State(TypesBits::decode(sub_minor_key())); } |
1453 NilValue nil, | |
1454 InitializationState init_state) | |
1455 : HydrogenCodeStub(isolate, init_state), nil_value_(nil) { } | |
1456 | 1458 |
1457 class NilValueField : public BitField<NilValue, 0, 1> {}; | 1459 class NilValueBits : public BitField<NilValue, 0, 1> {}; |
1458 class TypesField : public BitField<byte, 1, NUMBER_OF_TYPES> {}; | 1460 class TypesBits : public BitField<byte, 1, NUMBER_OF_TYPES> {}; |
1459 | 1461 |
1460 virtual Major MajorKey() const V8_OVERRIDE { return CompareNilIC; } | 1462 friend class CompareNilIC; |
1461 virtual int NotMissMinorKey() const { return GetExtraICState(); } | |
1462 | |
1463 NilValue nil_value_; | |
1464 State state_; | |
1465 | 1463 |
1466 DISALLOW_COPY_AND_ASSIGN(CompareNilICStub); | 1464 DISALLOW_COPY_AND_ASSIGN(CompareNilICStub); |
1467 }; | 1465 }; |
1468 | 1466 |
1469 | 1467 |
1470 OStream& operator<<(OStream& os, const CompareNilICStub::State& s); | 1468 OStream& operator<<(OStream& os, const CompareNilICStub::State& s); |
1471 | 1469 |
1472 | 1470 |
1473 class CEntryStub : public PlatformCodeStub { | 1471 class CEntryStub : public PlatformCodeStub { |
1474 public: | 1472 public: |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1960 private: | 1958 private: |
1961 virtual void Generate(MacroAssembler* masm); | 1959 virtual void Generate(MacroAssembler* masm); |
1962 | 1960 |
1963 DISALLOW_COPY_AND_ASSIGN(KeyedLoadICTrampolineStub); | 1961 DISALLOW_COPY_AND_ASSIGN(KeyedLoadICTrampolineStub); |
1964 }; | 1962 }; |
1965 | 1963 |
1966 | 1964 |
1967 class VectorLoadStub : public HydrogenCodeStub { | 1965 class VectorLoadStub : public HydrogenCodeStub { |
1968 public: | 1966 public: |
1969 explicit VectorLoadStub(Isolate* isolate, const LoadIC::State& state) | 1967 explicit VectorLoadStub(Isolate* isolate, const LoadIC::State& state) |
1970 : HydrogenCodeStub(isolate), state_(state) {} | 1968 : HydrogenCodeStub(isolate) { |
| 1969 set_sub_minor_key(state.GetExtraICState()); |
| 1970 } |
1971 | 1971 |
1972 virtual Handle<Code> GenerateCode() V8_OVERRIDE; | 1972 virtual Handle<Code> GenerateCode() V8_OVERRIDE; |
1973 | 1973 |
1974 virtual void InitializeInterfaceDescriptor( | 1974 virtual void InitializeInterfaceDescriptor( |
1975 CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; | 1975 CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE; |
1976 | 1976 |
1977 static void InstallDescriptors(Isolate* isolate); | 1977 static void InstallDescriptors(Isolate* isolate); |
1978 | 1978 |
1979 virtual Code::Kind GetCodeKind() const V8_OVERRIDE { return Code::LOAD_IC; } | 1979 virtual Code::Kind GetCodeKind() const V8_OVERRIDE { return Code::LOAD_IC; } |
1980 | 1980 |
1981 virtual InlineCacheState GetICState() const V8_FINAL V8_OVERRIDE { | 1981 virtual InlineCacheState GetICState() const V8_FINAL V8_OVERRIDE { |
1982 return GENERIC; | 1982 return GENERIC; |
1983 } | 1983 } |
1984 | 1984 |
1985 virtual ExtraICState GetExtraICState() const V8_FINAL V8_OVERRIDE { | 1985 virtual ExtraICState GetExtraICState() const V8_FINAL V8_OVERRIDE { |
1986 return state_.GetExtraICState(); | 1986 return static_cast<ExtraICState>(sub_minor_key()); |
1987 } | 1987 } |
1988 | 1988 |
| 1989 private: |
1989 virtual Major MajorKey() const V8_OVERRIDE { return VectorLoad; } | 1990 virtual Major MajorKey() const V8_OVERRIDE { return VectorLoad; } |
1990 | 1991 |
1991 private: | 1992 LoadIC::State state() const { return LoadIC::State(GetExtraICState()); } |
1992 int NotMissMinorKey() const { return state_.GetExtraICState(); } | |
1993 | |
1994 const LoadIC::State state_; | |
1995 | 1993 |
1996 DISALLOW_COPY_AND_ASSIGN(VectorLoadStub); | 1994 DISALLOW_COPY_AND_ASSIGN(VectorLoadStub); |
1997 }; | 1995 }; |
1998 | 1996 |
1999 | 1997 |
2000 class VectorKeyedLoadStub : public VectorLoadStub { | 1998 class VectorKeyedLoadStub : public VectorLoadStub { |
2001 public: | 1999 public: |
2002 explicit VectorKeyedLoadStub(Isolate* isolate) | 2000 explicit VectorKeyedLoadStub(Isolate* isolate) |
2003 : VectorLoadStub(isolate, LoadIC::State(0)) {} | 2001 : VectorLoadStub(isolate, LoadIC::State(0)) {} |
2004 | 2002 |
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2624 | 2622 |
2625 void Generate(MacroAssembler* masm); | 2623 void Generate(MacroAssembler* masm); |
2626 | 2624 |
2627 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); | 2625 DISALLOW_COPY_AND_ASSIGN(ProfileEntryHookStub); |
2628 }; | 2626 }; |
2629 | 2627 |
2630 | 2628 |
2631 } } // namespace v8::internal | 2629 } } // namespace v8::internal |
2632 | 2630 |
2633 #endif // V8_CODE_STUBS_H_ | 2631 #endif // V8_CODE_STUBS_H_ |
OLD | NEW |