1 // Copyright 2013 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_ALLOCATION_SITE_SCOPES_H_ 6 #define V8_ALLOCATION_SITE_SCOPES_H_ 7 8 #include "src/handles.h" 9 #include "src/objects.h" 10 #include "src/objects/map.h" 11 12 namespace v8 { 13 namespace internal { 14 15 // AllocationSiteContext is the base class for walking and copying a nested 16 // boilerplate with AllocationSite and AllocationMemento support. 17 class AllocationSiteContext { 18 public: AllocationSiteContext(Isolate * isolate)19 explicit AllocationSiteContext(Isolate* isolate) { 20 isolate_ = isolate; 21 } 22 top()23 Handle<AllocationSite> top() { return top_; } current()24 Handle<AllocationSite> current() { return current_; } 25 ShouldCreateMemento(Handle<JSObject> object)26 bool ShouldCreateMemento(Handle<JSObject> object) { return false; } 27 isolate()28 Isolate* isolate() { return isolate_; } 29 30 protected: update_current_site(AllocationSite * site)31 void update_current_site(AllocationSite* site) { 32 *(current_.location()) = site; 33 } 34 InitializeTraversal(Handle<AllocationSite> site)35 void InitializeTraversal(Handle<AllocationSite> site) { 36 top_ = site; 37 // {current_} is updated in place to not create unnecessary Handles, hence 38 // we initially need a separate handle. 39 current_ = Handle<AllocationSite>::New(*top_, isolate()); 40 } 41 42 private: 43 Isolate* isolate_; 44 Handle<AllocationSite> top_; 45 Handle<AllocationSite> current_; 46 }; 47 48 49 // AllocationSiteUsageContext aids in the creation of AllocationMementos placed 50 // behind some/all components of a copied object literal. 51 class AllocationSiteUsageContext : public AllocationSiteContext { 52 public: AllocationSiteUsageContext(Isolate * isolate,Handle<AllocationSite> site,bool activated)53 AllocationSiteUsageContext(Isolate* isolate, Handle<AllocationSite> site, 54 bool activated) 55 : AllocationSiteContext(isolate), 56 top_site_(site), 57 activated_(activated) { } 58 EnterNewScope()59 inline Handle<AllocationSite> EnterNewScope() { 60 if (top().is_null()) { 61 InitializeTraversal(top_site_); 62 } else { 63 // Advance current site 64 Object* nested_site = current()->nested_site(); 65 // Something is wrong if we advance to the end of the list here. 66 update_current_site(AllocationSite::cast(nested_site)); 67 } 68 return Handle<AllocationSite>(*current(), isolate()); 69 } 70 ExitScope(Handle<AllocationSite> scope_site,Handle<JSObject> object)71 inline void ExitScope(Handle<AllocationSite> scope_site, 72 Handle<JSObject> object) { 73 // This assert ensures that we are pointing at the right sub-object in a 74 // recursive walk of a nested literal. 75 DCHECK(object.is_null() || *object == scope_site->boilerplate()); 76 } 77 ShouldCreateMemento(Handle<JSObject> object)78 bool ShouldCreateMemento(Handle<JSObject> object) { 79 if (activated_ && 80 AllocationSite::CanTrack(object->map()->instance_type())) { 81 if (FLAG_allocation_site_pretenuring || 82 AllocationSite::ShouldTrack(object->GetElementsKind())) { 83 if (FLAG_trace_creation_allocation_sites) { 84 PrintF("*** Creating Memento for %s %p\n", 85 object->IsJSArray() ? "JSArray" : "JSObject", 86 static_cast<void*>(*object)); 87 } 88 return true; 89 } 90 } 91 return false; 92 } 93 94 static const bool kCopying = true; 95 96 private: 97 Handle<AllocationSite> top_site_; 98 bool activated_; 99 }; 100 101 102 } // namespace internal 103 } // namespace v8 104 105 #endif // V8_ALLOCATION_SITE_SCOPES_H_ 106