1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved. 2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file. 4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compilation-dependencies.h" 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/factory.h" 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/handles-inl.h" 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate.h" 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/objects-inl.h" 11f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/zone/zone.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 { 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal { 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDependentCode* CompilationDependencies::Get(Handle<Object> object) { 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (object->IsMap()) { 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Handle<Map>::cast(object)->dependent_code(); 19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (object->IsPropertyCell()) { 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Handle<PropertyCell>::cast(object)->dependent_code(); 21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (object->IsAllocationSite()) { 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return Handle<AllocationSite>::cast(object)->dependent_code(); 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return nullptr; 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CompilationDependencies::Set(Handle<Object> object, 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<DependentCode> dep) { 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (object->IsMap()) { 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map>::cast(object)->set_dependent_code(*dep); 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (object->IsPropertyCell()) { 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<PropertyCell>::cast(object)->set_dependent_code(*dep); 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (object->IsAllocationSite()) { 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<AllocationSite>::cast(object)->set_dependent_code(*dep); 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UNREACHABLE(); 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CompilationDependencies::Insert(DependentCode::DependencyGroup group, 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<HeapObject> object) { 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (groups_[group] == nullptr) { 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch groups_[group] = new (zone_) ZoneList<Handle<HeapObject>>(2, zone_); 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch groups_[group]->Add(object, zone_); 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (object_wrapper_.is_null()) { 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Allocate the wrapper if necessary. 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object_wrapper_ = 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate_->factory()->NewForeign(reinterpret_cast<Address>(this)); 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Get the old dependent code list. 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<DependentCode> old_dependent_code = 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<DependentCode>(Get(object), isolate_); 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<DependentCode> new_dependent_code = 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DependentCode::InsertCompilationDependencies(old_dependent_code, group, 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch object_wrapper_); 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Set the new dependent code list if the head of the list changed. 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!new_dependent_code.is_identical_to(old_dependent_code)) { 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Set(object, new_dependent_code); 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CompilationDependencies::Commit(Handle<Code> code) { 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsEmpty()) return; 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!object_wrapper_.is_null()); 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<WeakCell> cell = Code::WeakCellFor(code); 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference get_wrapper; 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < DependentCode::kGroupCount; i++) { 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ZoneList<Handle<HeapObject>>* group_objects = groups_[i]; 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (group_objects == nullptr) continue; 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DependentCode::DependencyGroup group = 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<DependentCode::DependencyGroup>(i); 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int j = 0; j < group_objects->length(); j++) { 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DependentCode* dependent_code = Get(group_objects->at(j)); 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch dependent_code->UpdateToFinishedCode(group, *object_wrapper_, *cell); 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch groups_[i] = nullptr; // Zone-allocated, no need to delete. 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CompilationDependencies::Rollback() { 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IsEmpty()) return; 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AllowDeferredHandleDereference get_wrapper; 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Unregister from all dependent maps if not yet committed. 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 0; i < DependentCode::kGroupCount; i++) { 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ZoneList<Handle<HeapObject>>* group_objects = groups_[i]; 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (group_objects == nullptr) continue; 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DependentCode::DependencyGroup group = 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static_cast<DependentCode::DependencyGroup>(i); 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int j = 0; j < group_objects->length(); j++) { 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DependentCode* dependent_code = Get(group_objects->at(j)); 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch dependent_code->RemoveCompilationDependencies(group, *object_wrapper_); 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch groups_[i] = nullptr; // Zone-allocated, no need to delete. 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CompilationDependencies::AssumeMapNotDeprecated(Handle<Map> map) { 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!map->is_deprecated()); 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Do nothing if the map cannot be deprecated. 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->CanBeDeprecated()) { 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Insert(DependentCode::kTransitionGroup, map); 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CompilationDependencies::AssumeMapStable(Handle<Map> map) { 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(map->is_stable()); 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Do nothing if the map cannot transition. 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->CanTransition()) { 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Insert(DependentCode::kPrototypeCheckGroup, map); 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CompilationDependencies::AssumePrototypeMapsStable( 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> map, MaybeHandle<JSReceiver> prototype) { 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (PrototypeIterator i(map); !i.IsAtEnd(); i.Advance()) { 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSReceiver> const current = 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrototypeIterator::GetCurrent<JSReceiver>(i); 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AssumeMapStable(handle(current->map())); 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSReceiver> last; 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (prototype.ToHandle(&last) && last.is_identical_to(current)) { 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch break; 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid CompilationDependencies::AssumeTransitionStable( 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<AllocationSite> site) { 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Do nothing if the object doesn't have any useful element transitions left. 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ElementsKind kind = 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch site->SitePointsToLiteral() 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? JSObject::cast(site->transition_info())->GetElementsKind() 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : site->GetElementsKind(); 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) { 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Insert(DependentCode::kAllocationSiteTransitionChangedGroup, site); 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 155