| 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 |