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_IC_H_ | 5 #ifndef V8_IC_H_ |
6 #define V8_IC_H_ | 6 #define V8_IC_H_ |
7 | 7 |
8 #include "macro-assembler.h" | 8 #include "macro-assembler.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
11 namespace internal { | 11 namespace internal { |
12 | 12 |
13 | 13 |
14 const int kMaxKeyedPolymorphism = 4; | 14 const int kMaxKeyedPolymorphism = 4; |
15 | 15 |
16 | 16 |
17 // IC_UTIL_LIST defines all utility functions called from generated | 17 // IC_UTIL_LIST defines all utility functions called from generated |
18 // inline caching code. The argument for the macro, ICU, is the function name. | 18 // inline caching code. The argument for the macro, ICU, is the function name. |
19 #define IC_UTIL_LIST(ICU) \ | 19 #define IC_UTIL_LIST(ICU) \ |
20 ICU(LoadIC_Miss) \ | 20 ICU(LoadIC_Miss) \ |
21 ICU(KeyedLoadIC_Miss) \ | 21 ICU(KeyedLoadIC_Miss) \ |
22 ICU(CallIC_Miss) \ | 22 ICU(CallIC_Miss) \ |
| 23 ICU(CallIC_Customization_Miss) \ |
23 ICU(StoreIC_Miss) \ | 24 ICU(StoreIC_Miss) \ |
24 ICU(StoreIC_ArrayLength) \ | 25 ICU(StoreIC_ArrayLength) \ |
25 ICU(StoreIC_Slow) \ | 26 ICU(StoreIC_Slow) \ |
26 ICU(SharedStoreIC_ExtendStorage) \ | 27 ICU(SharedStoreIC_ExtendStorage) \ |
27 ICU(KeyedStoreIC_Miss) \ | 28 ICU(KeyedStoreIC_Miss) \ |
28 ICU(KeyedStoreIC_Slow) \ | 29 ICU(KeyedStoreIC_Slow) \ |
29 /* Utilities for IC stubs. */ \ | 30 /* Utilities for IC stubs. */ \ |
30 ICU(StoreCallbackProperty) \ | 31 ICU(StoreCallbackProperty) \ |
31 ICU(LoadPropertyWithInterceptorOnly) \ | 32 ICU(LoadPropertyWithInterceptorOnly) \ |
32 ICU(LoadPropertyWithInterceptorForLoad) \ | 33 ICU(LoadPropertyWithInterceptorForLoad) \ |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 IC::UtilityId id() const { return id_; } | 327 IC::UtilityId id() const { return id_; } |
327 private: | 328 private: |
328 Address address_; | 329 Address address_; |
329 IC::UtilityId id_; | 330 IC::UtilityId id_; |
330 }; | 331 }; |
331 | 332 |
332 | 333 |
333 class CallIC: public IC { | 334 class CallIC: public IC { |
334 public: | 335 public: |
335 enum CallType { METHOD, FUNCTION }; | 336 enum CallType { METHOD, FUNCTION }; |
336 enum StubType { DEFAULT, MONOMORPHIC_ARRAY }; | |
337 | 337 |
338 class State V8_FINAL BASE_EMBEDDED { | 338 class State V8_FINAL BASE_EMBEDDED { |
339 public: | 339 public: |
340 explicit State(ExtraICState extra_ic_state); | 340 explicit State(ExtraICState extra_ic_state); |
341 | 341 |
342 static State MonomorphicArrayCallState(int argc, CallType call_type) { | 342 State(int argc, CallType call_type) |
343 return State(argc, call_type, MONOMORPHIC_ARRAY); | 343 : argc_(argc), call_type_(call_type) { |
344 } | 344 } |
345 | 345 |
346 static State DefaultCallState(int argc, CallType call_type) { | 346 InlineCacheState GetICState() const { return ::v8::internal::GENERIC; } |
347 return State(argc, call_type, DEFAULT); | |
348 } | |
349 | |
350 // Transition from the current state to another. | |
351 State ToGenericState() const { | |
352 return DefaultCallState(arg_count(), call_type()); | |
353 } | |
354 | |
355 State ToMonomorphicArrayCallState() const { | |
356 return MonomorphicArrayCallState(arg_count(), call_type()); | |
357 } | |
358 | |
359 InlineCacheState GetICState() const { | |
360 return stub_type_ == CallIC::DEFAULT | |
361 ? ::v8::internal::GENERIC | |
362 : ::v8::internal::MONOMORPHIC; | |
363 } | |
364 | 347 |
365 ExtraICState GetExtraICState() const; | 348 ExtraICState GetExtraICState() const; |
366 | 349 |
367 static void GenerateAheadOfTime( | 350 static void GenerateAheadOfTime( |
368 Isolate*, void (*Generate)(Isolate*, const State&)); | 351 Isolate*, void (*Generate)(Isolate*, const State&)); |
369 | 352 |
370 int arg_count() const { return argc_; } | 353 int arg_count() const { return argc_; } |
371 CallType call_type() const { return call_type_; } | 354 CallType call_type() const { return call_type_; } |
372 StubType stub_type() const { return stub_type_; } | |
373 | 355 |
374 bool CallAsMethod() const { return call_type_ == METHOD; } | 356 bool CallAsMethod() const { return call_type_ == METHOD; } |
375 | 357 |
376 void Print(StringStream* stream) const; | 358 void Print(StringStream* stream) const; |
377 | 359 |
378 bool operator==(const State& other_state) const { | |
379 return (argc_ == other_state.argc_ && | |
380 call_type_ == other_state.call_type_ && | |
381 stub_type_ == other_state.stub_type_); | |
382 } | |
383 | |
384 bool operator!=(const State& other_state) const { | |
385 return !(*this == other_state); | |
386 } | |
387 | |
388 private: | 360 private: |
389 State(int argc, CallType call_type, StubType stub_type) | |
390 : argc_(argc), | |
391 call_type_(call_type), | |
392 stub_type_(stub_type) { | |
393 } | |
394 | |
395 class ArgcBits: public BitField<int, 0, Code::kArgumentsBits> {}; | 361 class ArgcBits: public BitField<int, 0, Code::kArgumentsBits> {}; |
396 class CallTypeBits: public BitField<CallType, Code::kArgumentsBits, 1> {}; | 362 class CallTypeBits: public BitField<CallType, Code::kArgumentsBits, 1> {}; |
397 class StubTypeBits: | |
398 public BitField<StubType, Code::kArgumentsBits + 1, 1> {}; // NOLINT | |
399 | 363 |
400 const int argc_; | 364 const int argc_; |
401 const CallType call_type_; | 365 const CallType call_type_; |
402 const StubType stub_type_; | |
403 }; | 366 }; |
404 | 367 |
405 explicit CallIC(Isolate* isolate) | 368 explicit CallIC(Isolate* isolate) |
406 : IC(EXTRA_CALL_FRAME, isolate) { | 369 : IC(EXTRA_CALL_FRAME, isolate) { |
407 } | 370 } |
408 | 371 |
| 372 void PatchMegamorphic(Handle<FixedArray> vector, Handle<Smi> slot); |
| 373 |
409 void HandleMiss(Handle<Object> receiver, | 374 void HandleMiss(Handle<Object> receiver, |
410 Handle<Object> function, | 375 Handle<Object> function, |
411 Handle<FixedArray> vector, | 376 Handle<FixedArray> vector, |
412 Handle<Smi> slot); | 377 Handle<Smi> slot); |
413 | 378 |
414 // Returns true if a custom handler was installed. | 379 // Returns true if a custom handler was installed. |
415 bool DoCustomHandler(Handle<Object> receiver, | 380 bool DoCustomHandler(Handle<Object> receiver, |
416 Handle<Object> function, | 381 Handle<Object> function, |
417 Handle<FixedArray> vector, | 382 Handle<FixedArray> vector, |
418 Handle<Smi> slot, | 383 Handle<Smi> slot, |
419 const State& new_state); | 384 const State& state); |
420 | 385 |
421 // Code generator routines. | 386 // Code generator routines. |
422 static Handle<Code> initialize_stub(Isolate* isolate, | 387 static Handle<Code> initialize_stub(Isolate* isolate, |
423 int argc, | 388 int argc, |
424 CallType call_type); | 389 CallType call_type); |
425 | 390 |
426 static void Clear(Isolate* isolate, Address address, Code* target, | 391 static void Clear(Isolate* isolate, Address address, Code* target, |
427 ConstantPoolArray* constant_pool); | 392 ConstantPoolArray* constant_pool); |
428 }; | 393 }; |
429 | 394 |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1056 DECLARE_RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss); | 1021 DECLARE_RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss); |
1057 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_Miss); | 1022 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_Miss); |
1058 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite); | 1023 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite); |
1059 DECLARE_RUNTIME_FUNCTION(CompareNilIC_Miss); | 1024 DECLARE_RUNTIME_FUNCTION(CompareNilIC_Miss); |
1060 DECLARE_RUNTIME_FUNCTION(ToBooleanIC_Miss); | 1025 DECLARE_RUNTIME_FUNCTION(ToBooleanIC_Miss); |
1061 | 1026 |
1062 | 1027 |
1063 } } // namespace v8::internal | 1028 } } // namespace v8::internal |
1064 | 1029 |
1065 #endif // V8_IC_H_ | 1030 #endif // V8_IC_H_ |
OLD | NEW |