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 11 namespace v8 { 12 namespace internal { 13 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: 19 explicit AllocationSiteContext(Isolate* isolate) { 20 isolate_ = isolate; 21 } 22 23 Handle<AllocationSite> top() { return top_; } 24 Handle<AllocationSite> current() { return current_; } 25 26 bool ShouldCreateMemento(Handle<JSObject> object) { return false; } 27 28 Isolate* isolate() { return isolate_; } 29 30 protected: 31 void update_current_site(AllocationSite* site) { 32 *(current_.location()) = site; 33 } 34 35 void InitializeTraversal(Handle<AllocationSite> site) { 36 top_ = site; 37 current_ = Handle<AllocationSite>::New(*top_, isolate()); 38 } 39 40 private: 41 Isolate* isolate_; 42 Handle<AllocationSite> top_; 43 Handle<AllocationSite> current_; 44 }; 45 46 47 // AllocationSiteCreationContext aids in the creation of AllocationSites to 48 // accompany object literals. 49 class AllocationSiteCreationContext : public AllocationSiteContext { 50 public: 51 explicit AllocationSiteCreationContext(Isolate* isolate) 52 : AllocationSiteContext(isolate) { } 53 54 Handle<AllocationSite> EnterNewScope(); 55 void ExitScope(Handle<AllocationSite> site, Handle<JSObject> object); 56 }; 57 58 59 // AllocationSiteUsageContext aids in the creation of AllocationMementos placed 60 // behind some/all components of a copied object literal. 61 class AllocationSiteUsageContext : public AllocationSiteContext { 62 public: 63 AllocationSiteUsageContext(Isolate* isolate, Handle<AllocationSite> site, 64 bool activated) 65 : AllocationSiteContext(isolate), 66 top_site_(site), 67 activated_(activated) { } 68 69 inline Handle<AllocationSite> EnterNewScope() { 70 if (top().is_null()) { 71 InitializeTraversal(top_site_); 72 } else { 73 // Advance current site 74 Object* nested_site = current()->nested_site(); 75 // Something is wrong if we advance to the end of the list here. 76 update_current_site(AllocationSite::cast(nested_site)); 77 } 78 return Handle<AllocationSite>(*current(), isolate()); 79 } 80 81 inline void ExitScope(Handle<AllocationSite> scope_site, 82 Handle<JSObject> object) { 83 // This assert ensures that we are pointing at the right sub-object in a 84 // recursive walk of a nested literal. 85 DCHECK(object.is_null() || *object == scope_site->transition_info()); 86 } 87 88 bool ShouldCreateMemento(Handle<JSObject> object); 89 90 private: 91 Handle<AllocationSite> top_site_; 92 bool activated_; 93 }; 94 95 96 } // namespace internal 97 } // namespace v8 98 99 #endif // V8_ALLOCATION_SITE_SCOPES_H_ 100