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