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