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 "src/ic/ic-state.h" | 8 #include "src/ic/ic-state.h" |
9 #include "src/macro-assembler.h" | 9 #include "src/macro-assembler.h" |
10 | 10 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 static void RegisterWeakMapDependency(Handle<Code> stub); | 81 static void RegisterWeakMapDependency(Handle<Code> stub); |
82 | 82 |
83 // This function is called when a weak map in the stub is dying, | 83 // This function is called when a weak map in the stub is dying, |
84 // invalidates the stub by setting maps in it to undefined. | 84 // invalidates the stub by setting maps in it to undefined. |
85 static void InvalidateMaps(Code* stub); | 85 static void InvalidateMaps(Code* stub); |
86 | 86 |
87 // Clear the inline cache to initial state. | 87 // Clear the inline cache to initial state. |
88 static void Clear(Isolate* isolate, Address address, | 88 static void Clear(Isolate* isolate, Address address, |
89 ConstantPoolArray* constant_pool); | 89 ConstantPoolArray* constant_pool); |
90 | 90 |
91 // Clear the vector-based inline cache to initial state. | |
92 template <class Nexus> | |
93 static void Clear(Isolate* isolate, Code::Kind kind, Code* host, | |
94 Nexus* nexus); | |
95 | |
96 #ifdef DEBUG | 91 #ifdef DEBUG |
97 bool IsLoadStub() const { | 92 bool IsLoadStub() const { |
98 return target()->is_load_stub() || target()->is_keyed_load_stub(); | 93 return target()->is_load_stub() || target()->is_keyed_load_stub(); |
99 } | 94 } |
100 | 95 |
101 bool IsStoreStub() const { | 96 bool IsStoreStub() const { |
102 return target()->is_store_stub() || target()->is_keyed_store_stub(); | 97 return target()->is_store_stub() || target()->is_keyed_store_stub(); |
103 } | 98 } |
104 | 99 |
105 bool IsCallStub() const { return target()->is_call_stub(); } | 100 bool IsCallStub() const { return target()->is_call_stub(); } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 | 154 |
160 bool UseVector() const { | 155 bool UseVector() const { |
161 bool use = (FLAG_vector_ics && | 156 bool use = (FLAG_vector_ics && |
162 (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC)) || | 157 (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC)) || |
163 kind() == Code::CALL_IC; | 158 kind() == Code::CALL_IC; |
164 // If we are supposed to use the nexus, verify the nexus is non-null. | 159 // If we are supposed to use the nexus, verify the nexus is non-null. |
165 DCHECK(!use || nexus_ != NULL); | 160 DCHECK(!use || nexus_ != NULL); |
166 return use; | 161 return use; |
167 } | 162 } |
168 | 163 |
| 164 // Configure for most states. |
| 165 void ConfigureVectorState(IC::State new_state); |
| 166 // Configure the vector for MONOMORPHIC. |
| 167 void ConfigureVectorState(Handle<Name> name, Handle<HeapType> type, |
| 168 Handle<Code> handler); |
| 169 // Configure the vector for POLYMORPHIC. |
| 170 void ConfigureVectorState(Handle<Name> name, TypeHandleList* types, |
| 171 CodeHandleList* handlers); |
| 172 |
169 char TransitionMarkFromState(IC::State state); | 173 char TransitionMarkFromState(IC::State state); |
170 void TraceIC(const char* type, Handle<Object> name); | 174 void TraceIC(const char* type, Handle<Object> name); |
171 void TraceIC(const char* type, Handle<Object> name, State old_state, | 175 void TraceIC(const char* type, Handle<Object> name, State old_state, |
172 State new_state); | 176 State new_state); |
173 | 177 |
174 MaybeHandle<Object> TypeError(const char* type, Handle<Object> object, | 178 MaybeHandle<Object> TypeError(const char* type, Handle<Object> object, |
175 Handle<Object> key); | 179 Handle<Object> key); |
176 MaybeHandle<Object> ReferenceError(const char* type, Handle<Name> name); | 180 MaybeHandle<Object> ReferenceError(const char* type, Handle<Name> name); |
177 | 181 |
178 // Access the target code for the given IC address. | 182 // Access the target code for the given IC address. |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 inline Code* get_host(); | 269 inline Code* get_host(); |
266 | 270 |
267 private: | 271 private: |
268 inline Code* raw_target() const; | 272 inline Code* raw_target() const; |
269 inline ConstantPoolArray* constant_pool() const; | 273 inline ConstantPoolArray* constant_pool() const; |
270 inline ConstantPoolArray* raw_constant_pool() const; | 274 inline ConstantPoolArray* raw_constant_pool() const; |
271 | 275 |
272 void FindTargetMaps() { | 276 void FindTargetMaps() { |
273 if (target_maps_set_) return; | 277 if (target_maps_set_) return; |
274 target_maps_set_ = true; | 278 target_maps_set_ = true; |
275 if (state_ == MONOMORPHIC) { | 279 if (UseVector()) { |
276 Map* map = target_->FindFirstMap(); | 280 nexus()->ExtractMaps(&target_maps_); |
277 if (map != NULL) target_maps_.Add(handle(map)); | 281 } else { |
278 } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) { | 282 if (state_ == MONOMORPHIC) { |
279 target_->FindAllMaps(&target_maps_); | 283 Map* map = target_->FindFirstMap(); |
| 284 if (map != NULL) target_maps_.Add(handle(map)); |
| 285 } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) { |
| 286 target_->FindAllMaps(&target_maps_); |
| 287 } |
280 } | 288 } |
281 } | 289 } |
282 | 290 |
283 // Frame pointer for the frame that uses (calls) the IC. | 291 // Frame pointer for the frame that uses (calls) the IC. |
284 Address fp_; | 292 Address fp_; |
285 | 293 |
286 // All access to the program counter of an IC structure is indirect | 294 // All access to the program counter of an IC structure is indirect |
287 // to make the code GC safe. This feature is crucial since | 295 // to make the code GC safe. This feature is crucial since |
288 // GetProperty and SetProperty are called and they in turn might | 296 // GetProperty and SetProperty are called and they in turn might |
289 // invoke the garbage collector. | 297 // invoke the garbage collector. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 class LoadIC : public IC { | 365 class LoadIC : public IC { |
358 public: | 366 public: |
359 static ExtraICState ComputeExtraICState(ContextualMode contextual_mode) { | 367 static ExtraICState ComputeExtraICState(ContextualMode contextual_mode) { |
360 return LoadICState(contextual_mode).GetExtraICState(); | 368 return LoadICState(contextual_mode).GetExtraICState(); |
361 } | 369 } |
362 | 370 |
363 ContextualMode contextual_mode() const { | 371 ContextualMode contextual_mode() const { |
364 return LoadICState::GetContextualMode(extra_ic_state()); | 372 return LoadICState::GetContextualMode(extra_ic_state()); |
365 } | 373 } |
366 | 374 |
367 explicit LoadIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) { | 375 LoadIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL) |
| 376 : IC(depth, isolate, nexus) { |
| 377 DCHECK(!FLAG_vector_ics || nexus != NULL); |
368 DCHECK(IsLoadStub()); | 378 DCHECK(IsLoadStub()); |
369 } | 379 } |
370 | 380 |
| 381 // TODO(mvstanton): The for_queries_only is because we have a case where we |
| 382 // construct an IC only to gather the contextual mode, and we don't have |
| 383 // vector/slot information. for_queries_only is a temporary hack to enable the |
| 384 // strong DCHECK protection around vector/slot. |
| 385 LoadIC(FrameDepth depth, Isolate* isolate, bool for_queries_only) |
| 386 : IC(depth, isolate, NULL, for_queries_only) { |
| 387 DCHECK(IsLoadStub()); |
| 388 } |
| 389 |
371 // Returns if this IC is for contextual (no explicit receiver) | 390 // Returns if this IC is for contextual (no explicit receiver) |
372 // access to properties. | 391 // access to properties. |
373 bool IsUndeclaredGlobal(Handle<Object> receiver) { | 392 bool IsUndeclaredGlobal(Handle<Object> receiver) { |
374 if (receiver->IsGlobalObject()) { | 393 if (receiver->IsGlobalObject()) { |
375 return contextual_mode() == CONTEXTUAL; | 394 return contextual_mode() == CONTEXTUAL; |
376 } else { | 395 } else { |
377 DCHECK(contextual_mode() != CONTEXTUAL); | 396 DCHECK(contextual_mode() != CONTEXTUAL); |
378 return false; | 397 return false; |
379 } | 398 } |
380 } | 399 } |
381 | 400 |
382 // Code generator routines. | 401 // Code generator routines. |
383 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } | 402 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } |
384 static void GeneratePreMonomorphic(MacroAssembler* masm) { | 403 static void GeneratePreMonomorphic(MacroAssembler* masm) { |
385 GenerateMiss(masm); | 404 GenerateMiss(masm); |
386 } | 405 } |
387 static void GenerateMiss(MacroAssembler* masm); | 406 static void GenerateMiss(MacroAssembler* masm); |
388 static void GenerateNormal(MacroAssembler* masm); | 407 static void GenerateNormal(MacroAssembler* masm); |
389 static void GenerateRuntimeGetProperty(MacroAssembler* masm); | 408 static void GenerateRuntimeGetProperty(MacroAssembler* masm); |
390 | 409 |
391 static Handle<Code> initialize_stub(Isolate* isolate, | 410 static Handle<Code> initialize_stub(Isolate* isolate, |
392 ExtraICState extra_state); | 411 ExtraICState extra_state); |
393 static Handle<Code> initialize_stub_in_optimized_code( | 412 static Handle<Code> initialize_stub_in_optimized_code( |
394 Isolate* isolate, ExtraICState extra_state); | 413 Isolate* isolate, ExtraICState extra_state); |
395 | 414 |
396 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, | 415 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, |
397 Handle<Name> name); | 416 Handle<Name> name); |
398 | 417 |
| 418 static void Clear(Isolate* isolate, Code* host, LoadICNexus* nexus); |
| 419 |
399 protected: | 420 protected: |
400 inline void set_target(Code* code); | 421 inline void set_target(Code* code); |
401 | 422 |
402 Handle<Code> slow_stub() const { | 423 Handle<Code> slow_stub() const { |
403 if (kind() == Code::LOAD_IC) { | 424 if (kind() == Code::LOAD_IC) { |
404 return isolate()->builtins()->LoadIC_Slow(); | 425 return isolate()->builtins()->LoadIC_Slow(); |
405 } else { | 426 } else { |
406 DCHECK_EQ(Code::KEYED_LOAD_IC, kind()); | 427 DCHECK_EQ(Code::KEYED_LOAD_IC, kind()); |
407 return isolate()->builtins()->KeyedLoadIC_Slow(); | 428 return isolate()->builtins()->KeyedLoadIC_Slow(); |
408 } | 429 } |
(...skipping 18 matching lines...) Expand all Loading... |
427 | 448 |
428 static void Clear(Isolate* isolate, Address address, Code* target, | 449 static void Clear(Isolate* isolate, Address address, Code* target, |
429 ConstantPoolArray* constant_pool); | 450 ConstantPoolArray* constant_pool); |
430 | 451 |
431 friend class IC; | 452 friend class IC; |
432 }; | 453 }; |
433 | 454 |
434 | 455 |
435 class KeyedLoadIC : public LoadIC { | 456 class KeyedLoadIC : public LoadIC { |
436 public: | 457 public: |
437 explicit KeyedLoadIC(FrameDepth depth, Isolate* isolate) | 458 KeyedLoadIC(FrameDepth depth, Isolate* isolate, |
438 : LoadIC(depth, isolate) { | 459 KeyedLoadICNexus* nexus = NULL) |
| 460 : LoadIC(depth, isolate, nexus) { |
| 461 DCHECK(!FLAG_vector_ics || nexus != NULL); |
439 DCHECK(target()->is_keyed_load_stub()); | 462 DCHECK(target()->is_keyed_load_stub()); |
440 } | 463 } |
441 | 464 |
442 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, | 465 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, |
443 Handle<Object> key); | 466 Handle<Object> key); |
444 | 467 |
445 // Code generator routines. | 468 // Code generator routines. |
446 static void GenerateMiss(MacroAssembler* masm); | 469 static void GenerateMiss(MacroAssembler* masm); |
447 static void GenerateRuntimeGetProperty(MacroAssembler* masm); | 470 static void GenerateRuntimeGetProperty(MacroAssembler* masm); |
448 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } | 471 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); } |
449 static void GeneratePreMonomorphic(MacroAssembler* masm) { | 472 static void GeneratePreMonomorphic(MacroAssembler* masm) { |
450 GenerateMiss(masm); | 473 GenerateMiss(masm); |
451 } | 474 } |
452 static void GenerateGeneric(MacroAssembler* masm); | 475 static void GenerateGeneric(MacroAssembler* masm); |
453 | 476 |
454 // Bit mask to be tested against bit field for the cases when | 477 // Bit mask to be tested against bit field for the cases when |
455 // generic stub should go into slow case. | 478 // generic stub should go into slow case. |
456 // Access check is necessary explicitly since generic stub does not perform | 479 // Access check is necessary explicitly since generic stub does not perform |
457 // map checks. | 480 // map checks. |
458 static const int kSlowCaseBitFieldMask = | 481 static const int kSlowCaseBitFieldMask = |
459 (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor); | 482 (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor); |
460 | 483 |
461 static Handle<Code> initialize_stub(Isolate* isolate); | 484 static Handle<Code> initialize_stub(Isolate* isolate); |
462 static Handle<Code> initialize_stub_in_optimized_code(Isolate* isolate); | 485 static Handle<Code> initialize_stub_in_optimized_code(Isolate* isolate); |
463 static Handle<Code> generic_stub(Isolate* isolate); | 486 static Handle<Code> generic_stub(Isolate* isolate); |
464 static Handle<Code> pre_monomorphic_stub(Isolate* isolate); | 487 static Handle<Code> pre_monomorphic_stub(Isolate* isolate); |
465 | 488 |
| 489 static void Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus); |
| 490 |
466 protected: | 491 protected: |
467 // receiver is HeapObject because it could be a String or a JSObject | 492 // receiver is HeapObject because it could be a String or a JSObject |
468 Handle<Code> LoadElementStub(Handle<HeapObject> receiver); | 493 Handle<Code> LoadElementStub(Handle<HeapObject> receiver); |
469 virtual Handle<Code> pre_monomorphic_stub() const { | 494 virtual Handle<Code> pre_monomorphic_stub() const { |
470 return pre_monomorphic_stub(isolate()); | 495 return pre_monomorphic_stub(isolate()); |
471 } | 496 } |
472 | 497 |
473 private: | 498 private: |
474 Handle<Code> generic_stub() const { return generic_stub(isolate()); } | 499 Handle<Code> generic_stub() const { return generic_stub(isolate()); } |
475 | 500 |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 | 757 |
733 // Support functions for interceptor handlers. | 758 // Support functions for interceptor handlers. |
734 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly); | 759 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly); |
735 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptor); | 760 DECLARE_RUNTIME_FUNCTION(LoadPropertyWithInterceptor); |
736 DECLARE_RUNTIME_FUNCTION(LoadElementWithInterceptor); | 761 DECLARE_RUNTIME_FUNCTION(LoadElementWithInterceptor); |
737 DECLARE_RUNTIME_FUNCTION(StorePropertyWithInterceptor); | 762 DECLARE_RUNTIME_FUNCTION(StorePropertyWithInterceptor); |
738 } | 763 } |
739 } // namespace v8::internal | 764 } // namespace v8::internal |
740 | 765 |
741 #endif // V8_IC_H_ | 766 #endif // V8_IC_H_ |
OLD | NEW |