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

Side by Side Diff: src/ic.h

Issue 9310117: Implement KeyedStoreICs to grow arrays on out-of-bound stores. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add missing WB stub Created 8 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 }; 370 };
371 371
372 372
373 class KeyedIC: public IC { 373 class KeyedIC: public IC {
374 public: 374 public:
375 enum StubKind { 375 enum StubKind {
376 LOAD, 376 LOAD,
377 STORE_NO_TRANSITION, 377 STORE_NO_TRANSITION,
378 STORE_TRANSITION_SMI_TO_OBJECT, 378 STORE_TRANSITION_SMI_TO_OBJECT,
379 STORE_TRANSITION_SMI_TO_DOUBLE, 379 STORE_TRANSITION_SMI_TO_DOUBLE,
380 STORE_TRANSITION_DOUBLE_TO_OBJECT 380 STORE_TRANSITION_DOUBLE_TO_OBJECT,
381 STORE_AND_GROW_NO_TRANSITION,
382 STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT,
383 STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE,
384 STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT
381 }; 385 };
386
387 static const int kGrowICDelta = STORE_AND_GROW_NO_TRANSITION -
388 STORE_NO_TRANSITION;
389 STATIC_ASSERT(kGrowICDelta ==
390 STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT -
391 STORE_TRANSITION_SMI_TO_OBJECT);
392 STATIC_ASSERT(kGrowICDelta ==
393 STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE -
394 STORE_TRANSITION_SMI_TO_DOUBLE);
395 STATIC_ASSERT(kGrowICDelta ==
396 STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT -
397 STORE_TRANSITION_DOUBLE_TO_OBJECT);
398
382 explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {} 399 explicit KeyedIC(Isolate* isolate) : IC(NO_EXTRA_FRAME, isolate) {}
383 virtual ~KeyedIC() {} 400 virtual ~KeyedIC() {}
384 401
402 static inline KeyedAccessGrowMode GetGrowModeFromStubKind(
403 StubKind stub_kind) {
404 return (stub_kind >= STORE_AND_GROW_NO_TRANSITION)
405 ? ALLOW_JSARRAY_GROWTH
406 : DO_NOT_ALLOW_JSARRAY_GROWTH;
407 }
408
409 static inline StubKind GetGrowStubKind(StubKind stub_kind) {
410 ASSERT(stub_kind != LOAD);
411 if (stub_kind < STORE_AND_GROW_NO_TRANSITION) {
412 stub_kind = static_cast<StubKind>(static_cast<int>(stub_kind) +
413 kGrowICDelta);
414 }
415 return stub_kind;
416 }
417
385 virtual Handle<Code> GetElementStubWithoutMapCheck( 418 virtual Handle<Code> GetElementStubWithoutMapCheck(
386 bool is_js_array, 419 bool is_js_array,
387 ElementsKind elements_kind) = 0; 420 ElementsKind elements_kind,
421 KeyedAccessGrowMode grow_mode) = 0;
388 422
389 protected: 423 protected:
390 virtual Handle<Code> string_stub() { 424 virtual Handle<Code> string_stub() {
391 return Handle<Code>::null(); 425 return Handle<Code>::null();
392 } 426 }
393 427
394 virtual Code::Kind kind() const = 0; 428 virtual Code::Kind kind() const = 0;
395 429
396 Handle<Code> ComputeStub(Handle<JSObject> receiver, 430 Handle<Code> ComputeStub(Handle<JSObject> receiver,
397 StubKind stub_kind, 431 StubKind stub_kind,
398 StrictModeFlag strict_mode, 432 StrictModeFlag strict_mode,
399 Handle<Code> default_stub); 433 Handle<Code> default_stub);
400 434
401 virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps, 435 virtual Handle<Code> ComputePolymorphicStub(
402 StrictModeFlag strict_mode) = 0; 436 MapHandleList* receiver_maps,
437 StrictModeFlag strict_mode,
438 KeyedAccessGrowMode grow_mode) = 0;
403 439
404 Handle<Code> ComputeMonomorphicStubWithoutMapCheck( 440 Handle<Code> ComputeMonomorphicStubWithoutMapCheck(
405 Handle<Map> receiver_map, 441 Handle<Map> receiver_map,
406 StrictModeFlag strict_mode); 442 StrictModeFlag strict_mode,
443 KeyedAccessGrowMode grow_mode);
407 444
408 private: 445 private:
409 void GetReceiverMapsForStub(Handle<Code> stub, MapHandleList* result); 446 void GetReceiverMapsForStub(Handle<Code> stub, MapHandleList* result);
410 447
411 Handle<Code> ComputeMonomorphicStub(Handle<JSObject> receiver, 448 Handle<Code> ComputeMonomorphicStub(Handle<JSObject> receiver,
412 StubKind stub_kind, 449 StubKind stub_kind,
413 StrictModeFlag strict_mode, 450 StrictModeFlag strict_mode,
414 Handle<Code> default_stub); 451 Handle<Code> default_stub);
415 452
416 Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver, 453 Handle<Map> ComputeTransitionedMap(Handle<JSObject> receiver,
417 StubKind stub_kind); 454 StubKind stub_kind);
418 455
419 static bool IsTransitionStubKind(StubKind stub_kind) { 456 static bool IsTransitionStubKind(StubKind stub_kind) {
420 return stub_kind > STORE_NO_TRANSITION; 457 return stub_kind > STORE_NO_TRANSITION &&
458 stub_kind != STORE_AND_GROW_NO_TRANSITION;
459 }
460
461 static bool IsGrowStubKind(StubKind stub_kind) {
462 return stub_kind >= STORE_AND_GROW_NO_TRANSITION;
421 } 463 }
422 }; 464 };
423 465
424 466
425 class KeyedLoadIC: public KeyedIC { 467 class KeyedLoadIC: public KeyedIC {
426 public: 468 public:
427 explicit KeyedLoadIC(Isolate* isolate) : KeyedIC(isolate) { 469 explicit KeyedLoadIC(Isolate* isolate) : KeyedIC(isolate) {
428 ASSERT(target()->is_keyed_load_stub()); 470 ASSERT(target()->is_keyed_load_stub());
429 } 471 }
430 472
(...skipping 18 matching lines...) Expand all
449 491
450 // Bit mask to be tested against bit field for the cases when 492 // Bit mask to be tested against bit field for the cases when
451 // generic stub should go into slow case. 493 // generic stub should go into slow case.
452 // Access check is necessary explicitly since generic stub does not perform 494 // Access check is necessary explicitly since generic stub does not perform
453 // map checks. 495 // map checks.
454 static const int kSlowCaseBitFieldMask = 496 static const int kSlowCaseBitFieldMask =
455 (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor); 497 (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
456 498
457 virtual Handle<Code> GetElementStubWithoutMapCheck( 499 virtual Handle<Code> GetElementStubWithoutMapCheck(
458 bool is_js_array, 500 bool is_js_array,
459 ElementsKind elements_kind); 501 ElementsKind elements_kind,
502 KeyedAccessGrowMode grow_mode);
460 503
461 virtual bool IsGeneric() const { 504 virtual bool IsGeneric() const {
462 return target() == *generic_stub(); 505 return target() == *generic_stub();
463 } 506 }
464 507
465 protected: 508 protected:
466 virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; } 509 virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; }
467 510
468 virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps, 511 virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
469 StrictModeFlag strict_mode); 512 StrictModeFlag strict_mode,
513 KeyedAccessGrowMode grow_mode);
470 514
471 virtual Handle<Code> string_stub() { 515 virtual Handle<Code> string_stub() {
472 return isolate()->builtins()->KeyedLoadIC_String(); 516 return isolate()->builtins()->KeyedLoadIC_String();
473 } 517 }
474 518
475 private: 519 private:
476 // Update the inline cache. 520 // Update the inline cache.
477 void UpdateCaches(LookupResult* lookup, 521 void UpdateCaches(LookupResult* lookup,
478 State state, 522 State state,
479 Handle<Object> object, 523 Handle<Object> object,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 // lookup result. 577 // lookup result.
534 void UpdateCaches(LookupResult* lookup, 578 void UpdateCaches(LookupResult* lookup,
535 State state, 579 State state,
536 StrictModeFlag strict_mode, 580 StrictModeFlag strict_mode,
537 Handle<JSObject> receiver, 581 Handle<JSObject> receiver,
538 Handle<String> name, 582 Handle<String> name,
539 Handle<Object> value); 583 Handle<Object> value);
540 584
541 void set_target(Code* code) { 585 void set_target(Code* code) {
542 // Strict mode must be preserved across IC patching. 586 // Strict mode must be preserved across IC patching.
543 ASSERT((code->extra_ic_state() & kStrictMode) == 587 ASSERT(Code::GetStrictMode(code->extra_ic_state()) ==
544 (target()->extra_ic_state() & kStrictMode)); 588 Code::GetStrictMode(target()->extra_ic_state()));
545 IC::set_target(code); 589 IC::set_target(code);
546 } 590 }
547 591
548 // Stub accessors. 592 // Stub accessors.
549 Code* megamorphic_stub() { 593 Code* megamorphic_stub() {
550 return isolate()->builtins()->builtin( 594 return isolate()->builtins()->builtin(
551 Builtins::kStoreIC_Megamorphic); 595 Builtins::kStoreIC_Megamorphic);
552 } 596 }
553 Code* megamorphic_stub_strict() { 597 Code* megamorphic_stub_strict() {
554 return isolate()->builtins()->builtin( 598 return isolate()->builtins()->builtin(
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 static void GenerateSlow(MacroAssembler* masm); 640 static void GenerateSlow(MacroAssembler* masm);
597 static void GenerateRuntimeSetProperty(MacroAssembler* masm, 641 static void GenerateRuntimeSetProperty(MacroAssembler* masm,
598 StrictModeFlag strict_mode); 642 StrictModeFlag strict_mode);
599 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode); 643 static void GenerateGeneric(MacroAssembler* masm, StrictModeFlag strict_mode);
600 static void GenerateNonStrictArguments(MacroAssembler* masm); 644 static void GenerateNonStrictArguments(MacroAssembler* masm);
601 static void GenerateTransitionElementsSmiToDouble(MacroAssembler* masm); 645 static void GenerateTransitionElementsSmiToDouble(MacroAssembler* masm);
602 static void GenerateTransitionElementsDoubleToObject(MacroAssembler* masm); 646 static void GenerateTransitionElementsDoubleToObject(MacroAssembler* masm);
603 647
604 virtual Handle<Code> GetElementStubWithoutMapCheck( 648 virtual Handle<Code> GetElementStubWithoutMapCheck(
605 bool is_js_array, 649 bool is_js_array,
606 ElementsKind elements_kind); 650 ElementsKind elements_kind,
651 KeyedAccessGrowMode grow_mode);
607 652
608 virtual bool IsGeneric() const { 653 virtual bool IsGeneric() const {
609 return target() == *generic_stub() || 654 return target() == *generic_stub() ||
610 target() == *generic_stub_strict(); 655 target() == *generic_stub_strict();
611 } 656 }
612 657
613 protected: 658 protected:
614 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } 659 virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }
615 660
616 virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps, 661 virtual Handle<Code> ComputePolymorphicStub(MapHandleList* receiver_maps,
617 StrictModeFlag strict_mode); 662 StrictModeFlag strict_mode,
663 KeyedAccessGrowMode grow_mode);
618 664
619 private: 665 private:
620 // Update the inline cache. 666 // Update the inline cache.
621 void UpdateCaches(LookupResult* lookup, 667 void UpdateCaches(LookupResult* lookup,
622 State state, 668 State state,
623 StrictModeFlag strict_mode, 669 StrictModeFlag strict_mode,
624 Handle<JSObject> receiver, 670 Handle<JSObject> receiver,
625 Handle<String> name, 671 Handle<String> name,
626 Handle<Object> value); 672 Handle<Object> value);
627 673
628 void set_target(Code* code) { 674 void set_target(Code* code) {
629 // Strict mode must be preserved across IC patching. 675 // Strict mode must be preserved across IC patching.
630 ASSERT((code->extra_ic_state() & kStrictMode) == 676 ASSERT(Code::GetStrictMode(code->extra_ic_state()) ==
631 (target()->extra_ic_state() & kStrictMode)); 677 Code::GetStrictMode(target()->extra_ic_state()));
632 IC::set_target(code); 678 IC::set_target(code);
633 } 679 }
634 680
635 // Stub accessors. 681 // Stub accessors.
636 static Code* initialize_stub() { 682 static Code* initialize_stub() {
637 return Isolate::Current()->builtins()->builtin( 683 return Isolate::Current()->builtins()->builtin(
638 Builtins::kKeyedStoreIC_Initialize); 684 Builtins::kKeyedStoreIC_Initialize);
639 } 685 }
640 static Code* initialize_stub_strict() { 686 static Code* initialize_stub_strict() {
641 return Isolate::Current()->builtins()->builtin( 687 return Isolate::Current()->builtins()->builtin(
(...skipping 10 matching lines...) Expand all
652 } 698 }
653 Handle<Code> generic_stub_strict() const { 699 Handle<Code> generic_stub_strict() const {
654 return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); 700 return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
655 } 701 }
656 Handle<Code> non_strict_arguments_stub() { 702 Handle<Code> non_strict_arguments_stub() {
657 return isolate()->builtins()->KeyedStoreIC_NonStrictArguments(); 703 return isolate()->builtins()->KeyedStoreIC_NonStrictArguments();
658 } 704 }
659 705
660 static void Clear(Address address, Code* target); 706 static void Clear(Address address, Code* target);
661 707
708 StubKind GetStubKind(Handle<JSObject> receiver,
709 Handle<Object> key,
710 Handle<Object> value);
711
662 friend class IC; 712 friend class IC;
663 }; 713 };
664 714
665 715
666 class UnaryOpIC: public IC { 716 class UnaryOpIC: public IC {
667 public: 717 public:
668 // sorted: increasingly more unspecific (ignoring UNINITIALIZED) 718 // sorted: increasingly more unspecific (ignoring UNINITIALIZED)
669 // TODO(svenpanne) Using enums+switch is an antipattern, use a class instead. 719 // TODO(svenpanne) Using enums+switch is an antipattern, use a class instead.
670 enum TypeInfo { 720 enum TypeInfo {
671 UNINITIALIZED, 721 UNINITIALIZED,
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 void patch(Code* code); 815 void patch(Code* code);
766 }; 816 };
767 817
768 818
769 // Helper for BinaryOpIC and CompareIC. 819 // Helper for BinaryOpIC and CompareIC.
770 void PatchInlinedSmiCode(Address address); 820 void PatchInlinedSmiCode(Address address);
771 821
772 } } // namespace v8::internal 822 } } // namespace v8::internal
773 823
774 #endif // V8_IC_H_ 824 #endif // V8_IC_H_
OLDNEW
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698