Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(254)

Side by Side Diff: src/ic/ic.h

Issue 1846963002: Use a dictionary-mode code cache on the map rather than a dual system. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comment Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ic/ia32/stub-cache-ia32.cc ('k') | src/ic/ic.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 17 matching lines...) Expand all
28 // JavaScript frames on the stack. 28 // JavaScript frames on the stack.
29 IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL); 29 IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL);
30 virtual ~IC() {} 30 virtual ~IC() {}
31 31
32 State state() const { return state_; } 32 State state() const { return state_; }
33 inline Address address() const; 33 inline Address address() const;
34 34
35 // Compute the current IC state based on the target stub, receiver and name. 35 // Compute the current IC state based on the target stub, receiver and name.
36 void UpdateState(Handle<Object> receiver, Handle<Object> name); 36 void UpdateState(Handle<Object> receiver, Handle<Object> name);
37 37
38 bool IsNameCompatibleWithPrototypeFailure(Handle<Object> name); 38 bool RecomputeHandlerForName(Handle<Object> name);
39 void MarkPrototypeFailure(Handle<Object> name) { 39 void MarkRecomputeHandler(Handle<Object> name) {
40 DCHECK(IsNameCompatibleWithPrototypeFailure(name)); 40 DCHECK(RecomputeHandlerForName(name));
41 old_state_ = state_; 41 old_state_ = state_;
42 state_ = PROTOTYPE_FAILURE; 42 state_ = RECOMPUTE_HANDLER;
43 } 43 }
44 44
45 // Clear the inline cache to initial state. 45 // Clear the inline cache to initial state.
46 static void Clear(Isolate* isolate, Address address, Address constant_pool); 46 static void Clear(Isolate* isolate, Address address, Address constant_pool);
47 47
48 #ifdef DEBUG 48 #ifdef DEBUG
49 bool IsLoadStub() const { 49 bool IsLoadStub() const {
50 return target()->is_load_stub() || target()->is_keyed_load_stub(); 50 return target()->is_load_stub() || target()->is_keyed_load_stub();
51 } 51 }
52 52
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 if (kind_ == Code::KEYED_LOAD_IC) return Code::LOAD_IC; 168 if (kind_ == Code::KEYED_LOAD_IC) return Code::LOAD_IC;
169 DCHECK(kind_ == Code::LOAD_IC || kind_ == Code::STORE_IC || 169 DCHECK(kind_ == Code::LOAD_IC || kind_ == Code::STORE_IC ||
170 kind_ == Code::KEYED_STORE_IC); 170 kind_ == Code::KEYED_STORE_IC);
171 return kind_; 171 return kind_;
172 } 172 }
173 virtual Handle<Code> megamorphic_stub() { 173 virtual Handle<Code> megamorphic_stub() {
174 UNREACHABLE(); 174 UNREACHABLE();
175 return Handle<Code>::null(); 175 return Handle<Code>::null();
176 } 176 }
177 177
178 bool TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, 178 bool ShouldRecomputeHandler(Handle<Object> receiver, Handle<String> name);
179 Handle<String> name);
180 179
181 ExtraICState extra_ic_state() const { return extra_ic_state_; } 180 ExtraICState extra_ic_state() const { return extra_ic_state_; }
182 void set_extra_ic_state(ExtraICState state) { extra_ic_state_ = state; } 181 void set_extra_ic_state(ExtraICState state) { extra_ic_state_ = state; }
183 182
184 Handle<Map> receiver_map() { return receiver_map_; } 183 Handle<Map> receiver_map() { return receiver_map_; }
185 void update_receiver_map(Handle<Object> receiver) { 184 void update_receiver_map(Handle<Object> receiver) {
186 if (receiver->IsSmi()) { 185 if (receiver->IsSmi()) {
187 receiver_map_ = isolate_->factory()->heap_number_map(); 186 receiver_map_ = isolate_->factory()->heap_number_map();
188 } else { 187 } else {
189 receiver_map_ = handle(HeapObject::cast(*receiver)->map()); 188 receiver_map_ = handle(HeapObject::cast(*receiver)->map());
(...skipping 10 matching lines...) Expand all
200 Map* FirstTargetMap() { 199 Map* FirstTargetMap() {
201 FindTargetMaps(); 200 FindTargetMaps();
202 return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL; 201 return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL;
203 } 202 }
204 203
205 inline void UpdateTarget(); 204 inline void UpdateTarget();
206 205
207 Handle<TypeFeedbackVector> vector() const { return nexus()->vector_handle(); } 206 Handle<TypeFeedbackVector> vector() const { return nexus()->vector_handle(); }
208 FeedbackVectorSlot slot() const { return nexus()->slot(); } 207 FeedbackVectorSlot slot() const { return nexus()->slot(); }
209 State saved_state() const { 208 State saved_state() const {
210 return state() == PROTOTYPE_FAILURE ? old_state_ : state(); 209 return state() == RECOMPUTE_HANDLER ? old_state_ : state();
211 } 210 }
212 211
213 template <class NexusClass> 212 template <class NexusClass>
214 NexusClass* casted_nexus() { 213 NexusClass* casted_nexus() {
215 return static_cast<NexusClass*>(nexus_); 214 return static_cast<NexusClass*>(nexus_);
216 } 215 }
217 FeedbackNexus* nexus() const { return nexus_; } 216 FeedbackNexus* nexus() const { return nexus_; }
218 217
219 inline Code* get_host(); 218 inline Code* get_host();
220 219
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 DCHECK(nexus != NULL); 308 DCHECK(nexus != NULL);
310 DCHECK(IsLoadStub()); 309 DCHECK(IsLoadStub());
311 } 310 }
312 311
313 bool ShouldThrowReferenceError(Handle<Object> receiver) { 312 bool ShouldThrowReferenceError(Handle<Object> receiver) {
314 return receiver->IsJSGlobalObject() && typeof_mode() == NOT_INSIDE_TYPEOF; 313 return receiver->IsJSGlobalObject() && typeof_mode() == NOT_INSIDE_TYPEOF;
315 } 314 }
316 315
317 // Code generator routines. 316 // Code generator routines.
318 317
319 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
320 static void GenerateMiss(MacroAssembler* masm); 318 static void GenerateMiss(MacroAssembler* masm);
321 static void GenerateRuntimeGetProperty(MacroAssembler* masm); 319 static void GenerateRuntimeGetProperty(MacroAssembler* masm);
322 static void GenerateNormal(MacroAssembler* masm); 320 static void GenerateNormal(MacroAssembler* masm);
323 321
324 static Handle<Code> initialize_stub(Isolate* isolate, 322 static Handle<Code> initialize_stub(Isolate* isolate,
325 ExtraICState extra_state); 323 ExtraICState extra_state);
326 static Handle<Code> initialize_stub_in_optimized_code( 324 static Handle<Code> initialize_stub_in_optimized_code(
327 Isolate* isolate, ExtraICState extra_state, State initialization_state); 325 Isolate* isolate, ExtraICState extra_state, State initialization_state);
328 326
329 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, 327 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
(...skipping 18 matching lines...) Expand all
348 // Update the inline cache and the global stub cache based on the 346 // Update the inline cache and the global stub cache based on the
349 // lookup result. 347 // lookup result.
350 void UpdateCaches(LookupIterator* lookup); 348 void UpdateCaches(LookupIterator* lookup);
351 349
352 Handle<Code> CompileHandler(LookupIterator* lookup, Handle<Object> unused, 350 Handle<Code> CompileHandler(LookupIterator* lookup, Handle<Object> unused,
353 CacheHolderFlag cache_holder) override; 351 CacheHolderFlag cache_holder) override;
354 352
355 private: 353 private:
356 Handle<Code> SimpleFieldLoad(FieldIndex index); 354 Handle<Code> SimpleFieldLoad(FieldIndex index);
357 355
358 static void Clear(Isolate* isolate, Address address, Code* target,
359 Address constant_pool);
360
361 friend class IC; 356 friend class IC;
362 }; 357 };
363 358
364 359
365 class KeyedLoadIC : public LoadIC { 360 class KeyedLoadIC : public LoadIC {
366 public: 361 public:
367 // ExtraICState bits (building on IC) 362 // ExtraICState bits (building on IC)
368 class IcCheckTypeField 363 class IcCheckTypeField
369 : public BitField<IcCheckType, LoadICState::kNextBitFieldOffset, 1> {}; 364 : public BitField<IcCheckType, LoadICState::kNextBitFieldOffset, 1> {};
370 365
(...skipping 13 matching lines...) Expand all
384 DCHECK(nexus != NULL); 379 DCHECK(nexus != NULL);
385 DCHECK(target()->is_keyed_load_stub()); 380 DCHECK(target()->is_keyed_load_stub());
386 } 381 }
387 382
388 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object, 383 MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
389 Handle<Object> key); 384 Handle<Object> key);
390 385
391 // Code generator routines. 386 // Code generator routines.
392 static void GenerateMiss(MacroAssembler* masm); 387 static void GenerateMiss(MacroAssembler* masm);
393 static void GenerateRuntimeGetProperty(MacroAssembler* masm); 388 static void GenerateRuntimeGetProperty(MacroAssembler* masm);
394 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
395 static void GenerateMegamorphic(MacroAssembler* masm); 389 static void GenerateMegamorphic(MacroAssembler* masm);
396 390
397 // Bit mask to be tested against bit field for the cases when 391 // Bit mask to be tested against bit field for the cases when
398 // generic stub should go into slow case. 392 // generic stub should go into slow case.
399 // Access check is necessary explicitly since generic stub does not perform 393 // Access check is necessary explicitly since generic stub does not perform
400 // map checks. 394 // map checks.
401 static const int kSlowCaseBitFieldMask = 395 static const int kSlowCaseBitFieldMask =
402 (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor); 396 (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
403 397
404 static Handle<Code> initialize_stub(Isolate* isolate, 398 static Handle<Code> initialize_stub(Isolate* isolate,
405 ExtraICState extra_state); 399 ExtraICState extra_state);
406 static Handle<Code> initialize_stub_in_optimized_code( 400 static Handle<Code> initialize_stub_in_optimized_code(
407 Isolate* isolate, State initialization_state, ExtraICState extra_state); 401 Isolate* isolate, State initialization_state, ExtraICState extra_state);
408 static Handle<Code> ChooseMegamorphicStub(Isolate* isolate, 402 static Handle<Code> ChooseMegamorphicStub(Isolate* isolate,
409 ExtraICState extra_state); 403 ExtraICState extra_state);
410 404
411 static void Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus); 405 static void Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus);
412 406
413 protected: 407 protected:
414 // receiver is HeapObject because it could be a String or a JSObject 408 // receiver is HeapObject because it could be a String or a JSObject
415 Handle<Code> LoadElementStub(Handle<HeapObject> receiver); 409 Handle<Code> LoadElementStub(Handle<HeapObject> receiver);
416 410
417 private: 411 private:
418 static void Clear(Isolate* isolate, Address address, Code* target,
419 Address constant_pool);
420
421 friend class IC; 412 friend class IC;
422 }; 413 };
423 414
424 415
425 class StoreIC : public IC { 416 class StoreIC : public IC {
426 public: 417 public:
427 static ExtraICState ComputeExtraICState(LanguageMode flag) { 418 static ExtraICState ComputeExtraICState(LanguageMode flag) {
428 return StoreICState(flag).GetExtraICState(); 419 return StoreICState(flag).GetExtraICState();
429 } 420 }
430 421
431 StoreIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL) 422 StoreIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL)
432 : IC(depth, isolate, nexus) { 423 : IC(depth, isolate, nexus) {
433 DCHECK(IsStoreStub()); 424 DCHECK(IsStoreStub());
434 } 425 }
435 426
436 LanguageMode language_mode() const { 427 LanguageMode language_mode() const {
437 return StoreICState::GetLanguageMode(extra_ic_state()); 428 return StoreICState::GetLanguageMode(extra_ic_state());
438 } 429 }
439 430
440 // Code generators for stub routines. Only called once at startup. 431 // Code generators for stub routines. Only called once at startup.
441 static void GenerateSlow(MacroAssembler* masm); 432 static void GenerateSlow(MacroAssembler* masm);
442 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
443 static void GeneratePreMonomorphic(MacroAssembler* masm) {
444 GenerateMiss(masm);
445 }
446 static void GenerateMiss(MacroAssembler* masm); 433 static void GenerateMiss(MacroAssembler* masm);
447 static void GenerateMegamorphic(MacroAssembler* masm); 434 static void GenerateMegamorphic(MacroAssembler* masm);
448 static void GenerateNormal(MacroAssembler* masm); 435 static void GenerateNormal(MacroAssembler* masm);
449 static void GenerateRuntimeSetProperty(MacroAssembler* masm, 436 static void GenerateRuntimeSetProperty(MacroAssembler* masm,
450 LanguageMode language_mode); 437 LanguageMode language_mode);
451 438
452 static Handle<Code> initialize_stub(Isolate* isolate, 439 static Handle<Code> initialize_stub(Isolate* isolate,
453 LanguageMode language_mode, 440 LanguageMode language_mode,
454 State initialization_state); 441 State initialization_state);
455 static Handle<Code> initialize_stub_in_optimized_code( 442 static Handle<Code> initialize_stub_in_optimized_code(
456 Isolate* isolate, LanguageMode language_mode, State initialization_state); 443 Isolate* isolate, LanguageMode language_mode, State initialization_state);
457 444
458 MUST_USE_RESULT MaybeHandle<Object> Store( 445 MUST_USE_RESULT MaybeHandle<Object> Store(
459 Handle<Object> object, Handle<Name> name, Handle<Object> value, 446 Handle<Object> object, Handle<Name> name, Handle<Object> value,
460 JSReceiver::StoreFromKeyed store_mode = 447 JSReceiver::StoreFromKeyed store_mode =
461 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED); 448 JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED);
462 449
463 bool LookupForWrite(LookupIterator* it, Handle<Object> value, 450 bool LookupForWrite(LookupIterator* it, Handle<Object> value,
464 JSReceiver::StoreFromKeyed store_mode); 451 JSReceiver::StoreFromKeyed store_mode);
465 452
466 static void Clear(Isolate* isolate, Code* host, StoreICNexus* nexus); 453 static void Clear(Isolate* isolate, Code* host, StoreICNexus* nexus);
467 454
468 protected: 455 protected:
469 // Stub accessors. 456 // Stub accessors.
470 Handle<Code> megamorphic_stub() override; 457 Handle<Code> megamorphic_stub() override;
471 Handle<Code> slow_stub() const; 458 Handle<Code> slow_stub() const;
472 459
473 virtual Handle<Code> pre_monomorphic_stub() const {
474 return pre_monomorphic_stub(isolate(), language_mode());
475 }
476
477 static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
478 LanguageMode language_mode);
479
480 // Update the inline cache and the global stub cache based on the 460 // Update the inline cache and the global stub cache based on the
481 // lookup result. 461 // lookup result.
482 void UpdateCaches(LookupIterator* lookup, Handle<Object> value, 462 void UpdateCaches(LookupIterator* lookup, Handle<Object> value,
483 JSReceiver::StoreFromKeyed store_mode); 463 JSReceiver::StoreFromKeyed store_mode);
484 Handle<Code> CompileHandler(LookupIterator* lookup, Handle<Object> value, 464 Handle<Code> CompileHandler(LookupIterator* lookup, Handle<Object> value,
485 CacheHolderFlag cache_holder) override; 465 CacheHolderFlag cache_holder) override;
486 466
487 private: 467 private:
488 inline void set_target(Code* code); 468 inline void set_target(Code* code);
489 469
490 static void Clear(Isolate* isolate, Address address, Code* target,
491 Address constant_pool);
492
493 friend class IC; 470 friend class IC;
494 }; 471 };
495 472
496 473
497 enum KeyedStoreCheckMap { kDontCheckMap, kCheckMap }; 474 enum KeyedStoreCheckMap { kDontCheckMap, kCheckMap };
498 475
499 476
500 enum KeyedStoreIncrementLength { kDontIncrementLength, kIncrementLength }; 477 enum KeyedStoreIncrementLength { kDontIncrementLength, kIncrementLength };
501 478
502 479
(...skipping 23 matching lines...) Expand all
526 KeyedStoreICNexus* nexus = NULL) 503 KeyedStoreICNexus* nexus = NULL)
527 : StoreIC(depth, isolate, nexus) { 504 : StoreIC(depth, isolate, nexus) {
528 DCHECK(target()->is_keyed_store_stub()); 505 DCHECK(target()->is_keyed_store_stub());
529 } 506 }
530 507
531 MUST_USE_RESULT MaybeHandle<Object> Store(Handle<Object> object, 508 MUST_USE_RESULT MaybeHandle<Object> Store(Handle<Object> object,
532 Handle<Object> name, 509 Handle<Object> name,
533 Handle<Object> value); 510 Handle<Object> value);
534 511
535 // Code generators for stub routines. Only called once at startup. 512 // Code generators for stub routines. Only called once at startup.
536 static void GenerateInitialize(MacroAssembler* masm) { GenerateMiss(masm); }
537 static void GeneratePreMonomorphic(MacroAssembler* masm) {
538 GenerateMiss(masm);
539 }
540 static void GenerateMiss(MacroAssembler* masm); 513 static void GenerateMiss(MacroAssembler* masm);
541 static void GenerateSlow(MacroAssembler* masm); 514 static void GenerateSlow(MacroAssembler* masm);
542 static void GenerateMegamorphic(MacroAssembler* masm, 515 static void GenerateMegamorphic(MacroAssembler* masm,
543 LanguageMode language_mode); 516 LanguageMode language_mode);
544 517
545 static Handle<Code> initialize_stub(Isolate* isolate, 518 static Handle<Code> initialize_stub(Isolate* isolate,
546 LanguageMode language_mode, 519 LanguageMode language_mode,
547 State initialization_state); 520 State initialization_state);
548 521
549 static Handle<Code> initialize_stub_in_optimized_code( 522 static Handle<Code> initialize_stub_in_optimized_code(
550 Isolate* isolate, LanguageMode language_mode, State initialization_state); 523 Isolate* isolate, LanguageMode language_mode, State initialization_state);
551 static Handle<Code> ChooseMegamorphicStub(Isolate* isolate, 524 static Handle<Code> ChooseMegamorphicStub(Isolate* isolate,
552 ExtraICState extra_state); 525 ExtraICState extra_state);
553 526
554 static void Clear(Isolate* isolate, Code* host, KeyedStoreICNexus* nexus); 527 static void Clear(Isolate* isolate, Code* host, KeyedStoreICNexus* nexus);
555 528
556 protected: 529 protected:
557 virtual Handle<Code> pre_monomorphic_stub() const {
558 return pre_monomorphic_stub(isolate(), language_mode());
559 }
560 static Handle<Code> pre_monomorphic_stub(Isolate* isolate,
561 LanguageMode language_mode) {
562 if (is_strict(language_mode)) {
563 return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict();
564 } else {
565 return isolate->builtins()->KeyedStoreIC_PreMonomorphic();
566 }
567 }
568
569 Handle<Code> StoreElementStub(Handle<Map> receiver_map, 530 Handle<Code> StoreElementStub(Handle<Map> receiver_map,
570 KeyedAccessStoreMode store_mode); 531 KeyedAccessStoreMode store_mode);
571 532
572 private: 533 private:
573 inline void set_target(Code* code); 534 inline void set_target(Code* code);
574 535
575 static void Clear(Isolate* isolate, Address address, Code* target,
576 Address constant_pool);
577
578 Handle<Map> ComputeTransitionedMap(Handle<Map> map, 536 Handle<Map> ComputeTransitionedMap(Handle<Map> map,
579 KeyedAccessStoreMode store_mode); 537 KeyedAccessStoreMode store_mode);
580 538
581 friend class IC; 539 friend class IC;
582 }; 540 };
583 541
584 542
585 // Type Recording BinaryOpIC, that records the types of the inputs and outputs. 543 // Type Recording BinaryOpIC, that records the types of the inputs and outputs.
586 class BinaryOpIC : public IC { 544 class BinaryOpIC : public IC {
587 public: 545 public:
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 592
635 // Helper for BinaryOpIC and CompareIC. 593 // Helper for BinaryOpIC and CompareIC.
636 enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK }; 594 enum InlinedSmiCheck { ENABLE_INLINED_SMI_CHECK, DISABLE_INLINED_SMI_CHECK };
637 void PatchInlinedSmiCode(Isolate* isolate, Address address, 595 void PatchInlinedSmiCode(Isolate* isolate, Address address,
638 InlinedSmiCheck check); 596 InlinedSmiCheck check);
639 597
640 } // namespace internal 598 } // namespace internal
641 } // namespace v8 599 } // namespace v8
642 600
643 #endif // V8_IC_H_ 601 #endif // V8_IC_H_
OLDNEW
« no previous file with comments | « src/ic/ia32/stub-cache-ia32.cc ('k') | src/ic/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698