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

Side by Side Diff: src/objects.cc

Issue 24250005: AllocationSites for all literals (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments. Created 7 years, 2 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/objects.h ('k') | src/runtime.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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
(...skipping 10 matching lines...) Expand all
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "accessors.h" 30 #include "accessors.h"
31 #include "allocation-site-scopes.h"
31 #include "api.h" 32 #include "api.h"
32 #include "arguments.h" 33 #include "arguments.h"
33 #include "bootstrapper.h" 34 #include "bootstrapper.h"
34 #include "codegen.h" 35 #include "codegen.h"
35 #include "cpu-profiler.h" 36 #include "cpu-profiler.h"
36 #include "debug.h" 37 #include "debug.h"
37 #include "deoptimizer.h" 38 #include "deoptimizer.h"
38 #include "date.h" 39 #include "date.h"
39 #include "elements.h" 40 #include "elements.h"
40 #include "execution.h" 41 #include "execution.h"
(...skipping 5567 matching lines...) Expand 10 before | Expand all | Expand 10 after
5608 MaybeObject* maybe_copy = map()->Copy(); 5609 MaybeObject* maybe_copy = map()->Copy();
5609 if (!maybe_copy->To(&new_map)) return maybe_copy; 5610 if (!maybe_copy->To(&new_map)) return maybe_copy;
5610 new_map->set_is_observed(true); 5611 new_map->set_is_observed(true);
5611 } 5612 }
5612 set_map(new_map); 5613 set_map(new_map);
5613 5614
5614 return heap->undefined_value(); 5615 return heap->undefined_value();
5615 } 5616 }
5616 5617
5617 5618
5619 Handle<JSObject> JSObject::Copy(Handle<JSObject> object,
5620 Handle<AllocationSite> site) {
5621 Isolate* isolate = object->GetIsolate();
5622 CALL_HEAP_FUNCTION(isolate,
5623 isolate->heap()->CopyJSObject(*object, *site), JSObject);
5624 }
5625
5626
5618 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { 5627 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) {
5619 Isolate* isolate = object->GetIsolate(); 5628 Isolate* isolate = object->GetIsolate();
5620 CALL_HEAP_FUNCTION(isolate, 5629 CALL_HEAP_FUNCTION(isolate,
5621 isolate->heap()->CopyJSObject(*object), JSObject); 5630 isolate->heap()->CopyJSObject(*object), JSObject);
5622 } 5631 }
5623 5632
5624 5633
5625 class JSObjectWalkVisitor { 5634 class JSObjectWalkVisitor {
5626 public: 5635 public:
5627 explicit JSObjectWalkVisitor() {} 5636 explicit JSObjectWalkVisitor(AllocationSiteContext* site_context) :
5637 site_context_(site_context) {}
5628 virtual ~JSObjectWalkVisitor() {} 5638 virtual ~JSObjectWalkVisitor() {}
5629 5639
5630 Handle<JSObject> Visit(Handle<JSObject> object) { 5640 Handle<JSObject> Visit(Handle<JSObject> object) {
5631 return StructureWalk(object); 5641 return StructureWalk(object);
5632 } 5642 }
5633 5643
5634 // Returns true if the visitor is a copying visitor.
5635 virtual bool is_copying() = 0; 5644 virtual bool is_copying() = 0;
5636 5645
5637 protected: 5646 protected:
5638 Handle<JSObject> StructureWalk(Handle<JSObject> object); 5647 Handle<JSObject> StructureWalk(Handle<JSObject> object);
5639 5648
5640 // The returned handle should point to a new object if the visitor is a 5649 // The returned handle will be used for the object in all subsequent usages.
5641 // copying visitor, otherwise it should be the same as the input object. 5650 // This allows VisitObject to make a copy of the object if desired.
5642 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) = 0; 5651 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) = 0;
5643
5644 // The returned handle should point to a new value if the visitor is a
5645 // copying visitor, otherwise it should be the same as the input value.
5646 virtual Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object, 5652 virtual Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object,
5647 Handle<JSObject> value) = 0; 5653 Handle<JSObject> value) = 0;
5654
5655 AllocationSiteContext* site_context() { return site_context_; }
5656
5657 private:
5658 AllocationSiteContext* site_context_;
5648 }; 5659 };
5649 5660
5650 5661
5651 class JSObjectCopyVisitor: public JSObjectWalkVisitor { 5662 class JSObjectCopyVisitor: public JSObjectWalkVisitor {
5652 public: 5663 public:
5653 explicit JSObjectCopyVisitor() {} 5664 explicit JSObjectCopyVisitor(AllocationSiteContext* site_context)
5665 : JSObjectWalkVisitor(site_context) {}
5654 5666
5655 virtual bool is_copying() V8_OVERRIDE { return true; } 5667 virtual bool is_copying() V8_OVERRIDE { return true; }
5656 5668
5657 protected: 5669 // The returned handle will be used for the object in all
5670 // subsequent usages. This allows VisitObject to make a copy
5671 // of the object if desired.
5658 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE { 5672 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE {
5659 return JSObject::Copy(object); 5673 // Only create a memento if
5674 // 1) we have a JSArray, and
5675 // 2) the elements kind is palatable
5676 // 3) allow_mementos is true
5677 Handle<JSObject> copy;
5678 if (site_context()->activated() &&
5679 AllocationSite::CanTrack(object->map()->instance_type()) &&
5680 AllocationSite::GetMode(object->GetElementsKind()) ==
5681 TRACK_ALLOCATION_SITE) {
5682 copy = JSObject::Copy(object, site_context()->current());
5683 } else {
5684 copy = JSObject::Copy(object);
5685 }
5686
5687 return copy;
5660 } 5688 }
5661 5689
5662 virtual Handle<JSObject> VisitElementOrProperty( 5690 virtual Handle<JSObject> VisitElementOrProperty(
5663 Handle<JSObject> object, 5691 Handle<JSObject> object,
5664 Handle<JSObject> value) V8_OVERRIDE { 5692 Handle<JSObject> value) V8_OVERRIDE {
5665 return StructureWalk(value); 5693 Handle<AllocationSite> current_site = site_context()->EnterNewScope();
5694 Handle<JSObject> copy_of_value = StructureWalk(value);
5695 site_context()->ExitScope(current_site, value);
5696 return copy_of_value;
5666 } 5697 }
5667 }; 5698 };
5668 5699
5700
5701 class JSObjectCreateAllocationSitesVisitor: public JSObjectWalkVisitor {
5702 public:
5703 explicit JSObjectCreateAllocationSitesVisitor(
5704 AllocationSiteContext* site_context)
5705 : JSObjectWalkVisitor(site_context) {}
5706
5707 virtual bool is_copying() V8_OVERRIDE { return false; }
5708
5709 // The returned handle will be used for the object in all
5710 // subsequent usages. This allows VisitObject to make a copy
5711 // of the object if desired.
5712 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE {
5713 return object;
5714 }
5715
5716 virtual Handle<JSObject> VisitElementOrProperty(
5717 Handle<JSObject> object,
5718 Handle<JSObject> value) V8_OVERRIDE {
5719 Handle<AllocationSite> current_site = site_context()->EnterNewScope();
5720 value = StructureWalk(value);
5721 site_context()->ExitScope(current_site, value);
5722 return value;
5723 }
5724 };
5725
5669 5726
5670 Handle<JSObject> JSObjectWalkVisitor::StructureWalk(Handle<JSObject> object) { 5727 Handle<JSObject> JSObjectWalkVisitor::StructureWalk(Handle<JSObject> object) {
5671 bool copying = is_copying(); 5728 bool copying = is_copying();
5672 Isolate* isolate = object->GetIsolate(); 5729 Isolate* isolate = object->GetIsolate();
5673 StackLimitCheck check(isolate); 5730 StackLimitCheck check(isolate);
5674 if (check.HasOverflowed()) { 5731 if (check.HasOverflowed()) {
5675 isolate->StackOverflow(); 5732 isolate->StackOverflow();
5676 return Handle<JSObject>::null(); 5733 return Handle<JSObject>::null();
5677 } 5734 }
5678 5735
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
5802 case EXTERNAL_DOUBLE_ELEMENTS: 5859 case EXTERNAL_DOUBLE_ELEMENTS:
5803 case FAST_DOUBLE_ELEMENTS: 5860 case FAST_DOUBLE_ELEMENTS:
5804 case FAST_HOLEY_DOUBLE_ELEMENTS: 5861 case FAST_HOLEY_DOUBLE_ELEMENTS:
5805 // No contained objects, nothing to do. 5862 // No contained objects, nothing to do.
5806 break; 5863 break;
5807 } 5864 }
5808 return copy; 5865 return copy;
5809 } 5866 }
5810 5867
5811 5868
5812 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) { 5869 Handle<JSObject> JSObject::DeepWalk(Handle<JSObject> object,
5813 JSObjectCopyVisitor v; 5870 AllocationSiteContext* site_context) {
5871 JSObjectCreateAllocationSitesVisitor v(site_context);
5872 Handle<JSObject> copy = v.Visit(object);
5873 ASSERT(!v.is_copying() && copy.is_identical_to(object));
5874 return copy;
5875 }
5876
5877
5878 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object,
5879 AllocationSiteContext* site_context) {
5880 JSObjectCopyVisitor v(site_context);
5814 Handle<JSObject> copy = v.Visit(object); 5881 Handle<JSObject> copy = v.Visit(object);
5815 ASSERT(v.is_copying() && !copy.is_identical_to(object)); 5882 ASSERT(v.is_copying() && !copy.is_identical_to(object));
5816 return copy; 5883 return copy;
5817 } 5884 }
5818 5885
5819 5886
5820 // Tests for the fast common case for property enumeration: 5887 // Tests for the fast common case for property enumeration:
5821 // - This object and all prototypes has an enum cache (which means that 5888 // - This object and all prototypes has an enum cache (which means that
5822 // it is no proxy, has no interceptors and needs no access checks). 5889 // it is no proxy, has no interceptors and needs no access checks).
5823 // - This object has no elements. 5890 // - This object has no elements.
(...skipping 6742 matching lines...) Expand 10 before | Expand all | Expand 10 after
12566 } 12633 }
12567 12634
12568 12635
12569 void JSObject::TransitionElementsKind(Handle<JSObject> object, 12636 void JSObject::TransitionElementsKind(Handle<JSObject> object,
12570 ElementsKind to_kind) { 12637 ElementsKind to_kind) {
12571 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), 12638 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
12572 object->TransitionElementsKind(to_kind)); 12639 object->TransitionElementsKind(to_kind));
12573 } 12640 }
12574 12641
12575 12642
12643 bool AllocationSite::IsNestedSite() {
12644 ASSERT(FLAG_trace_track_allocation_sites);
12645 Object* current = GetHeap()->allocation_sites_list();
12646 while (current != NULL && current->IsAllocationSite()) {
12647 AllocationSite* current_site = AllocationSite::cast(current);
12648 if (current_site->nested_site() == this) {
12649 return true;
12650 }
12651 current = current_site->weak_next();
12652 }
12653 return false;
12654 }
12655
12656
12576 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { 12657 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) {
12577 if (!FLAG_track_allocation_sites || !IsJSArray()) { 12658 if (!FLAG_track_allocation_sites || !IsJSArray()) {
12578 return this; 12659 return this;
12579 } 12660 }
12580 12661
12581 AllocationMemento* memento = AllocationMemento::FindForJSObject(this); 12662 AllocationMemento* memento = AllocationMemento::FindForJSObject(this);
12582 if (memento == NULL || !memento->IsValid()) { 12663 if (memento == NULL || !memento->IsValid()) {
12583 return this; 12664 return this;
12584 } 12665 }
12585 12666
12586 // Walk through to the Allocation Site 12667 // Walk through to the Allocation Site
12587 AllocationSite* site = memento->GetAllocationSite(); 12668 AllocationSite* site = memento->GetAllocationSite();
12588 if (site->IsLiteralSite()) { 12669 if (site->SitePointsToLiteral() &&
12670 site->transition_info()->IsJSArray()) {
12589 JSArray* transition_info = JSArray::cast(site->transition_info()); 12671 JSArray* transition_info = JSArray::cast(site->transition_info());
12590 ElementsKind kind = transition_info->GetElementsKind(); 12672 ElementsKind kind = transition_info->GetElementsKind();
12591 // if kind is holey ensure that to_kind is as well. 12673 // if kind is holey ensure that to_kind is as well.
12592 if (IsHoleyElementsKind(kind)) { 12674 if (IsHoleyElementsKind(kind)) {
12593 to_kind = GetHoleyElementsKind(to_kind); 12675 to_kind = GetHoleyElementsKind(to_kind);
12594 } 12676 }
12595 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { 12677 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
12596 // If the array is huge, it's not likely to be defined in a local 12678 // If the array is huge, it's not likely to be defined in a local
12597 // function, so we shouldn't make new instances of it very often. 12679 // function, so we shouldn't make new instances of it very often.
12598 uint32_t length = 0; 12680 uint32_t length = 0;
12599 CHECK(transition_info->length()->ToArrayIndex(&length)); 12681 CHECK(transition_info->length()->ToArrayIndex(&length));
12600 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) { 12682 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) {
12601 if (FLAG_trace_track_allocation_sites) { 12683 if (FLAG_trace_track_allocation_sites) {
12684 bool is_nested = site->IsNestedSite();
12602 PrintF( 12685 PrintF(
12603 "AllocationSite: JSArray %p boilerplate updated %s->%s\n", 12686 "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n",
12604 reinterpret_cast<void*>(this), 12687 reinterpret_cast<void*>(this),
12688 is_nested ? "(nested)" : "",
12605 ElementsKindToString(kind), 12689 ElementsKindToString(kind),
12606 ElementsKindToString(to_kind)); 12690 ElementsKindToString(to_kind));
12607 } 12691 }
12608 return transition_info->TransitionElementsKind(to_kind); 12692 return transition_info->TransitionElementsKind(to_kind);
12609 } 12693 }
12610 } 12694 }
12611 } else { 12695 } else {
12612 ElementsKind kind = site->GetElementsKind(); 12696 ElementsKind kind = site->GetElementsKind();
12613 // if kind is holey ensure that to_kind is as well. 12697 // if kind is holey ensure that to_kind is as well.
12614 if (IsHoleyElementsKind(kind)) { 12698 if (IsHoleyElementsKind(kind)) {
(...skipping 3659 matching lines...) Expand 10 before | Expand all | Expand 10 after
16274 #define ERROR_MESSAGES_TEXTS(C, T) T, 16358 #define ERROR_MESSAGES_TEXTS(C, T) T,
16275 static const char* error_messages_[] = { 16359 static const char* error_messages_[] = {
16276 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16360 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16277 }; 16361 };
16278 #undef ERROR_MESSAGES_TEXTS 16362 #undef ERROR_MESSAGES_TEXTS
16279 return error_messages_[reason]; 16363 return error_messages_[reason];
16280 } 16364 }
16281 16365
16282 16366
16283 } } // namespace v8::internal 16367 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698