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

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

Powered by Google App Engine
This is Rietveld 408576698