11cb0ef41Sopenharmony_ci// Copyright 2021 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 31cb0ef41Sopenharmony_ci// found in the LICENSE file. 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ci#include "src/compiler/heap-refs.h" 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci#ifdef ENABLE_SLOW_DCHECKS 81cb0ef41Sopenharmony_ci#include <algorithm> 91cb0ef41Sopenharmony_ci#endif 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ci#include "src/api/api-inl.h" 121cb0ef41Sopenharmony_ci#include "src/ast/modules.h" 131cb0ef41Sopenharmony_ci#include "src/base/optional.h" 141cb0ef41Sopenharmony_ci#include "src/base/platform/platform.h" 151cb0ef41Sopenharmony_ci#include "src/codegen/code-factory.h" 161cb0ef41Sopenharmony_ci#include "src/compiler/compilation-dependencies.h" 171cb0ef41Sopenharmony_ci#include "src/compiler/js-heap-broker.h" 181cb0ef41Sopenharmony_ci#include "src/execution/protectors-inl.h" 191cb0ef41Sopenharmony_ci#include "src/objects/allocation-site-inl.h" 201cb0ef41Sopenharmony_ci#include "src/objects/descriptor-array.h" 211cb0ef41Sopenharmony_ci#include "src/objects/heap-number-inl.h" 221cb0ef41Sopenharmony_ci#include "src/objects/js-array-buffer-inl.h" 231cb0ef41Sopenharmony_ci#include "src/objects/literal-objects-inl.h" 241cb0ef41Sopenharmony_ci#include "src/objects/property-cell.h" 251cb0ef41Sopenharmony_ci#include "src/objects/template-objects-inl.h" 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_cinamespace v8 { 281cb0ef41Sopenharmony_cinamespace internal { 291cb0ef41Sopenharmony_cinamespace compiler { 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_ci#define TRACE(broker, x) TRACE_BROKER(broker, x) 321cb0ef41Sopenharmony_ci#define TRACE_MISSING(broker, x) TRACE_BROKER_MISSING(broker, x) 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci// There are several kinds of ObjectData values. 351cb0ef41Sopenharmony_ci// 361cb0ef41Sopenharmony_ci// kSmi: The underlying V8 object is a Smi and the data is an instance of the 371cb0ef41Sopenharmony_ci// base class (ObjectData), i.e. it's basically just the handle. Because the 381cb0ef41Sopenharmony_ci// object is a Smi, it's safe to access the handle in order to extract the 391cb0ef41Sopenharmony_ci// number value, and AsSmi() does exactly that. 401cb0ef41Sopenharmony_ci// 411cb0ef41Sopenharmony_ci// kBackgroundSerializedHeapObject: The underlying V8 object is a HeapObject 421cb0ef41Sopenharmony_ci// and the data is an instance of the corresponding (most-specific) subclass, 431cb0ef41Sopenharmony_ci// e.g. JSFunctionData, which provides serialized information about the 441cb0ef41Sopenharmony_ci// object. Allows serialization from the background thread. 451cb0ef41Sopenharmony_ci// 461cb0ef41Sopenharmony_ci// kUnserializedHeapObject: The underlying V8 object is a HeapObject and the 471cb0ef41Sopenharmony_ci// data is an instance of the base class (ObjectData), i.e. it basically 481cb0ef41Sopenharmony_ci// carries no information other than the handle. 491cb0ef41Sopenharmony_ci// 501cb0ef41Sopenharmony_ci// kNeverSerializedHeapObject: The underlying V8 object is a (potentially 511cb0ef41Sopenharmony_ci// mutable) HeapObject and the data is an instance of ObjectData. Its handle 521cb0ef41Sopenharmony_ci// must be persistent so that the GC can update it at a safepoint. Via this 531cb0ef41Sopenharmony_ci// handle, the object can be accessed concurrently to the main thread. 541cb0ef41Sopenharmony_ci// 551cb0ef41Sopenharmony_ci// kUnserializedReadOnlyHeapObject: The underlying V8 object is a read-only 561cb0ef41Sopenharmony_ci// HeapObject and the data is an instance of ObjectData. For 571cb0ef41Sopenharmony_ci// ReadOnlyHeapObjects, it is OK to access heap even from off-thread, so 581cb0ef41Sopenharmony_ci// these objects need not be serialized. 591cb0ef41Sopenharmony_cienum ObjectDataKind { 601cb0ef41Sopenharmony_ci kSmi, 611cb0ef41Sopenharmony_ci kBackgroundSerializedHeapObject, 621cb0ef41Sopenharmony_ci kUnserializedHeapObject, 631cb0ef41Sopenharmony_ci kNeverSerializedHeapObject, 641cb0ef41Sopenharmony_ci kUnserializedReadOnlyHeapObject 651cb0ef41Sopenharmony_ci}; 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_cinamespace { 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_cibool IsReadOnlyHeapObjectForCompiler(PtrComprCageBase cage_base, 701cb0ef41Sopenharmony_ci HeapObject object) { 711cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 721cb0ef41Sopenharmony_ci // TODO(jgruber): Remove this compiler-specific predicate and use the plain 731cb0ef41Sopenharmony_ci // heap predicate instead. This would involve removing the special cases for 741cb0ef41Sopenharmony_ci // builtins. 751cb0ef41Sopenharmony_ci return (object.IsCode(cage_base) && Code::cast(object).is_builtin()) || 761cb0ef41Sopenharmony_ci ReadOnlyHeap::Contains(object); 771cb0ef41Sopenharmony_ci} 781cb0ef41Sopenharmony_ci 791cb0ef41Sopenharmony_ci} // namespace 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_ciclass ObjectData : public ZoneObject { 821cb0ef41Sopenharmony_ci public: 831cb0ef41Sopenharmony_ci ObjectData(JSHeapBroker* broker, ObjectData** storage, Handle<Object> object, 841cb0ef41Sopenharmony_ci ObjectDataKind kind) 851cb0ef41Sopenharmony_ci : object_(object), 861cb0ef41Sopenharmony_ci kind_(kind) 871cb0ef41Sopenharmony_ci#ifdef DEBUG 881cb0ef41Sopenharmony_ci , 891cb0ef41Sopenharmony_ci broker_(broker) 901cb0ef41Sopenharmony_ci#endif // DEBUG 911cb0ef41Sopenharmony_ci { 921cb0ef41Sopenharmony_ci // This assignment ensures we don't end up inserting the same object 931cb0ef41Sopenharmony_ci // in an endless recursion. 941cb0ef41Sopenharmony_ci *storage = this; 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci TRACE(broker, "Creating data " << this << " for handle " << object.address() 971cb0ef41Sopenharmony_ci << " (" << Brief(*object) << ")"); 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci // It is safe to access read only heap objects and builtins from a 1001cb0ef41Sopenharmony_ci // background thread. When we read fields of these objects, we may create 1011cb0ef41Sopenharmony_ci // ObjectData on the background thread even without a canonical handle 1021cb0ef41Sopenharmony_ci // scope. This is safe too since we don't create handles but just get 1031cb0ef41Sopenharmony_ci // handles from read only root table or builtins table which is what 1041cb0ef41Sopenharmony_ci // canonical scope uses as well. For all other objects we should have 1051cb0ef41Sopenharmony_ci // created ObjectData in canonical handle scope on the main thread. 1061cb0ef41Sopenharmony_ci Isolate* isolate = broker->isolate(); 1071cb0ef41Sopenharmony_ci CHECK_IMPLIES(broker->mode() == JSHeapBroker::kDisabled || 1081cb0ef41Sopenharmony_ci broker->mode() == JSHeapBroker::kSerializing, 1091cb0ef41Sopenharmony_ci isolate->handle_scope_data()->canonical_scope != nullptr); 1101cb0ef41Sopenharmony_ci CHECK_IMPLIES(broker->mode() == JSHeapBroker::kSerialized, 1111cb0ef41Sopenharmony_ci kind == kUnserializedReadOnlyHeapObject || kind == kSmi || 1121cb0ef41Sopenharmony_ci kind == kNeverSerializedHeapObject || 1131cb0ef41Sopenharmony_ci kind == kBackgroundSerializedHeapObject); 1141cb0ef41Sopenharmony_ci CHECK_IMPLIES( 1151cb0ef41Sopenharmony_ci kind == kUnserializedReadOnlyHeapObject, 1161cb0ef41Sopenharmony_ci object->IsHeapObject() && IsReadOnlyHeapObjectForCompiler( 1171cb0ef41Sopenharmony_ci isolate, HeapObject::cast(*object))); 1181cb0ef41Sopenharmony_ci } 1191cb0ef41Sopenharmony_ci 1201cb0ef41Sopenharmony_ci#define DECLARE_IS(Name) bool Is##Name() const; 1211cb0ef41Sopenharmony_ci HEAP_BROKER_OBJECT_LIST(DECLARE_IS) 1221cb0ef41Sopenharmony_ci#undef DECLARE_IS 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_ci#define DECLARE_AS(Name) Name##Data* As##Name(); 1251cb0ef41Sopenharmony_ci HEAP_BROKER_BACKGROUND_SERIALIZED_OBJECT_LIST(DECLARE_AS) 1261cb0ef41Sopenharmony_ci#undef DECLARE_AS 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci Handle<Object> object() const { return object_; } 1291cb0ef41Sopenharmony_ci ObjectDataKind kind() const { return kind_; } 1301cb0ef41Sopenharmony_ci bool is_smi() const { return kind_ == kSmi; } 1311cb0ef41Sopenharmony_ci bool should_access_heap() const { 1321cb0ef41Sopenharmony_ci return kind_ == kUnserializedHeapObject || 1331cb0ef41Sopenharmony_ci kind_ == kNeverSerializedHeapObject || 1341cb0ef41Sopenharmony_ci kind_ == kUnserializedReadOnlyHeapObject; 1351cb0ef41Sopenharmony_ci } 1361cb0ef41Sopenharmony_ci bool IsNull() const { return object_->IsNull(); } 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci#ifdef DEBUG 1391cb0ef41Sopenharmony_ci JSHeapBroker* broker() const { return broker_; } 1401cb0ef41Sopenharmony_ci#endif // DEBUG 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ci private: 1431cb0ef41Sopenharmony_ci Handle<Object> const object_; 1441cb0ef41Sopenharmony_ci ObjectDataKind const kind_; 1451cb0ef41Sopenharmony_ci#ifdef DEBUG 1461cb0ef41Sopenharmony_ci JSHeapBroker* const broker_; // For DCHECKs. 1471cb0ef41Sopenharmony_ci#endif // DEBUG 1481cb0ef41Sopenharmony_ci}; 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ciclass HeapObjectData : public ObjectData { 1511cb0ef41Sopenharmony_ci public: 1521cb0ef41Sopenharmony_ci HeapObjectData(JSHeapBroker* broker, ObjectData** storage, 1531cb0ef41Sopenharmony_ci Handle<HeapObject> object, ObjectDataKind kind); 1541cb0ef41Sopenharmony_ci 1551cb0ef41Sopenharmony_ci base::Optional<bool> TryGetBooleanValue(JSHeapBroker* broker) const; 1561cb0ef41Sopenharmony_ci ObjectData* map() const { return map_; } 1571cb0ef41Sopenharmony_ci InstanceType GetMapInstanceType() const; 1581cb0ef41Sopenharmony_ci 1591cb0ef41Sopenharmony_ci private: 1601cb0ef41Sopenharmony_ci base::Optional<bool> TryGetBooleanValueImpl(JSHeapBroker* broker) const; 1611cb0ef41Sopenharmony_ci 1621cb0ef41Sopenharmony_ci ObjectData* const map_; 1631cb0ef41Sopenharmony_ci}; 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ciclass PropertyCellData : public HeapObjectData { 1661cb0ef41Sopenharmony_ci public: 1671cb0ef41Sopenharmony_ci PropertyCellData(JSHeapBroker* broker, ObjectData** storage, 1681cb0ef41Sopenharmony_ci Handle<PropertyCell> object, ObjectDataKind kind); 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_ci bool Cache(JSHeapBroker* broker); 1711cb0ef41Sopenharmony_ci 1721cb0ef41Sopenharmony_ci PropertyDetails property_details() const { 1731cb0ef41Sopenharmony_ci CHECK(serialized()); 1741cb0ef41Sopenharmony_ci return property_details_; 1751cb0ef41Sopenharmony_ci } 1761cb0ef41Sopenharmony_ci 1771cb0ef41Sopenharmony_ci ObjectData* value() const { 1781cb0ef41Sopenharmony_ci DCHECK(serialized()); 1791cb0ef41Sopenharmony_ci return value_; 1801cb0ef41Sopenharmony_ci } 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci private: 1831cb0ef41Sopenharmony_ci PropertyDetails property_details_ = PropertyDetails::Empty(); 1841cb0ef41Sopenharmony_ci ObjectData* value_ = nullptr; 1851cb0ef41Sopenharmony_ci 1861cb0ef41Sopenharmony_ci bool serialized() const { return value_ != nullptr; } 1871cb0ef41Sopenharmony_ci}; 1881cb0ef41Sopenharmony_ci 1891cb0ef41Sopenharmony_cinamespace { 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ciZoneVector<Address> GetCFunctions(FixedArray function_overloads, Zone* zone) { 1921cb0ef41Sopenharmony_ci const int len = function_overloads.length() / 1931cb0ef41Sopenharmony_ci FunctionTemplateInfo::kFunctionOverloadEntrySize; 1941cb0ef41Sopenharmony_ci ZoneVector<Address> c_functions = ZoneVector<Address>(len, zone); 1951cb0ef41Sopenharmony_ci for (int i = 0; i < len; i++) { 1961cb0ef41Sopenharmony_ci c_functions[i] = v8::ToCData<Address>(function_overloads.get( 1971cb0ef41Sopenharmony_ci FunctionTemplateInfo::kFunctionOverloadEntrySize * i)); 1981cb0ef41Sopenharmony_ci } 1991cb0ef41Sopenharmony_ci return c_functions; 2001cb0ef41Sopenharmony_ci} 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ciZoneVector<const CFunctionInfo*> GetCSignatures(FixedArray function_overloads, 2031cb0ef41Sopenharmony_ci Zone* zone) { 2041cb0ef41Sopenharmony_ci const int len = function_overloads.length() / 2051cb0ef41Sopenharmony_ci FunctionTemplateInfo::kFunctionOverloadEntrySize; 2061cb0ef41Sopenharmony_ci ZoneVector<const CFunctionInfo*> c_signatures = 2071cb0ef41Sopenharmony_ci ZoneVector<const CFunctionInfo*>(len, zone); 2081cb0ef41Sopenharmony_ci for (int i = 0; i < len; i++) { 2091cb0ef41Sopenharmony_ci c_signatures[i] = v8::ToCData<const CFunctionInfo*>(function_overloads.get( 2101cb0ef41Sopenharmony_ci FunctionTemplateInfo::kFunctionOverloadEntrySize * i + 1)); 2111cb0ef41Sopenharmony_ci } 2121cb0ef41Sopenharmony_ci return c_signatures; 2131cb0ef41Sopenharmony_ci} 2141cb0ef41Sopenharmony_ci 2151cb0ef41Sopenharmony_ci} // namespace 2161cb0ef41Sopenharmony_ci 2171cb0ef41Sopenharmony_ciPropertyCellData::PropertyCellData(JSHeapBroker* broker, ObjectData** storage, 2181cb0ef41Sopenharmony_ci Handle<PropertyCell> object, 2191cb0ef41Sopenharmony_ci ObjectDataKind kind) 2201cb0ef41Sopenharmony_ci : HeapObjectData(broker, storage, object, kind) {} 2211cb0ef41Sopenharmony_ci 2221cb0ef41Sopenharmony_cibool PropertyCellData::Cache(JSHeapBroker* broker) { 2231cb0ef41Sopenharmony_ci if (serialized()) return true; 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ci TraceScope tracer(broker, this, "PropertyCellData::Serialize"); 2261cb0ef41Sopenharmony_ci auto cell = Handle<PropertyCell>::cast(object()); 2271cb0ef41Sopenharmony_ci 2281cb0ef41Sopenharmony_ci // While this code runs on a background thread, the property cell might 2291cb0ef41Sopenharmony_ci // undergo state transitions via calls to PropertyCell::Transition. These 2301cb0ef41Sopenharmony_ci // transitions follow a certain protocol on which we rely here to ensure that 2311cb0ef41Sopenharmony_ci // we only report success when we can guarantee consistent data. A key 2321cb0ef41Sopenharmony_ci // property is that after transitioning from cell type A to B (A != B), there 2331cb0ef41Sopenharmony_ci // will never be a transition back to A, unless A is kConstant and the new 2341cb0ef41Sopenharmony_ci // value is the hole (i.e. the property cell was invalidated, which is a final 2351cb0ef41Sopenharmony_ci // state). 2361cb0ef41Sopenharmony_ci 2371cb0ef41Sopenharmony_ci PropertyDetails property_details = cell->property_details(kAcquireLoad); 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_ci Handle<Object> value = 2401cb0ef41Sopenharmony_ci broker->CanonicalPersistentHandle(cell->value(kAcquireLoad)); 2411cb0ef41Sopenharmony_ci if (broker->ObjectMayBeUninitialized(value)) { 2421cb0ef41Sopenharmony_ci DCHECK(!broker->IsMainThread()); 2431cb0ef41Sopenharmony_ci return false; 2441cb0ef41Sopenharmony_ci } 2451cb0ef41Sopenharmony_ci 2461cb0ef41Sopenharmony_ci { 2471cb0ef41Sopenharmony_ci PropertyDetails property_details_again = 2481cb0ef41Sopenharmony_ci cell->property_details(kAcquireLoad); 2491cb0ef41Sopenharmony_ci if (property_details != property_details_again) { 2501cb0ef41Sopenharmony_ci DCHECK(!broker->IsMainThread()); 2511cb0ef41Sopenharmony_ci return false; 2521cb0ef41Sopenharmony_ci } 2531cb0ef41Sopenharmony_ci } 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_ci if (property_details.cell_type() == PropertyCellType::kInTransition) { 2561cb0ef41Sopenharmony_ci DCHECK(!broker->IsMainThread()); 2571cb0ef41Sopenharmony_ci return false; 2581cb0ef41Sopenharmony_ci } 2591cb0ef41Sopenharmony_ci 2601cb0ef41Sopenharmony_ci ObjectData* value_data = broker->TryGetOrCreateData(value); 2611cb0ef41Sopenharmony_ci if (value_data == nullptr) { 2621cb0ef41Sopenharmony_ci DCHECK(!broker->IsMainThread()); 2631cb0ef41Sopenharmony_ci return false; 2641cb0ef41Sopenharmony_ci } 2651cb0ef41Sopenharmony_ci 2661cb0ef41Sopenharmony_ci PropertyCell::CheckDataIsCompatible(property_details, *value); 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci DCHECK(!serialized()); 2691cb0ef41Sopenharmony_ci property_details_ = property_details; 2701cb0ef41Sopenharmony_ci value_ = value_data; 2711cb0ef41Sopenharmony_ci DCHECK(serialized()); 2721cb0ef41Sopenharmony_ci return true; 2731cb0ef41Sopenharmony_ci} 2741cb0ef41Sopenharmony_ci 2751cb0ef41Sopenharmony_ciclass JSReceiverData : public HeapObjectData { 2761cb0ef41Sopenharmony_ci public: 2771cb0ef41Sopenharmony_ci JSReceiverData(JSHeapBroker* broker, ObjectData** storage, 2781cb0ef41Sopenharmony_ci Handle<JSReceiver> object, ObjectDataKind kind) 2791cb0ef41Sopenharmony_ci : HeapObjectData(broker, storage, object, kind) {} 2801cb0ef41Sopenharmony_ci}; 2811cb0ef41Sopenharmony_ci 2821cb0ef41Sopenharmony_ciclass JSObjectData : public JSReceiverData { 2831cb0ef41Sopenharmony_ci public: 2841cb0ef41Sopenharmony_ci JSObjectData(JSHeapBroker* broker, ObjectData** storage, 2851cb0ef41Sopenharmony_ci Handle<JSObject> object, ObjectDataKind kind) 2861cb0ef41Sopenharmony_ci : JSReceiverData(broker, storage, object, kind) {} 2871cb0ef41Sopenharmony_ci}; 2881cb0ef41Sopenharmony_ci 2891cb0ef41Sopenharmony_cinamespace { 2901cb0ef41Sopenharmony_ci 2911cb0ef41Sopenharmony_cibase::Optional<ObjectRef> GetOwnFastDataPropertyFromHeap( 2921cb0ef41Sopenharmony_ci JSHeapBroker* broker, JSObjectRef holder, Representation representation, 2931cb0ef41Sopenharmony_ci FieldIndex field_index) { 2941cb0ef41Sopenharmony_ci base::Optional<Object> constant; 2951cb0ef41Sopenharmony_ci { 2961cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 2971cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = broker->cage_base(); 2981cb0ef41Sopenharmony_ci 2991cb0ef41Sopenharmony_ci // This check to ensure the live map is the same as the cached map to 3001cb0ef41Sopenharmony_ci // to protect us against reads outside the bounds of the heap. This could 3011cb0ef41Sopenharmony_ci // happen if the Ref was created in a prior GC epoch, and the object 3021cb0ef41Sopenharmony_ci // shrunk in size. It might end up at the edge of a heap boundary. If 3031cb0ef41Sopenharmony_ci // we see that the map is the same in this GC epoch, we are safe. 3041cb0ef41Sopenharmony_ci Map map = holder.object()->map(cage_base, kAcquireLoad); 3051cb0ef41Sopenharmony_ci if (*holder.map().object() != map) { 3061cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker, "Map changed for " << holder); 3071cb0ef41Sopenharmony_ci return {}; 3081cb0ef41Sopenharmony_ci } 3091cb0ef41Sopenharmony_ci 3101cb0ef41Sopenharmony_ci if (field_index.is_inobject()) { 3111cb0ef41Sopenharmony_ci constant = 3121cb0ef41Sopenharmony_ci holder.object()->RawInobjectPropertyAt(cage_base, map, field_index); 3131cb0ef41Sopenharmony_ci if (!constant.has_value()) { 3141cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING( 3151cb0ef41Sopenharmony_ci broker, "Constant field in " << holder << " is unsafe to read"); 3161cb0ef41Sopenharmony_ci return {}; 3171cb0ef41Sopenharmony_ci } 3181cb0ef41Sopenharmony_ci } else { 3191cb0ef41Sopenharmony_ci Object raw_properties_or_hash = 3201cb0ef41Sopenharmony_ci holder.object()->raw_properties_or_hash(cage_base, kRelaxedLoad); 3211cb0ef41Sopenharmony_ci // Ensure that the object is safe to inspect. 3221cb0ef41Sopenharmony_ci if (broker->ObjectMayBeUninitialized(raw_properties_or_hash)) { 3231cb0ef41Sopenharmony_ci return {}; 3241cb0ef41Sopenharmony_ci } 3251cb0ef41Sopenharmony_ci if (!raw_properties_or_hash.IsPropertyArray(cage_base)) { 3261cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING( 3271cb0ef41Sopenharmony_ci broker, 3281cb0ef41Sopenharmony_ci "Expected PropertyArray for backing store in " << holder << "."); 3291cb0ef41Sopenharmony_ci return {}; 3301cb0ef41Sopenharmony_ci } 3311cb0ef41Sopenharmony_ci PropertyArray properties = PropertyArray::cast(raw_properties_or_hash); 3321cb0ef41Sopenharmony_ci const int array_index = field_index.outobject_array_index(); 3331cb0ef41Sopenharmony_ci if (array_index < properties.length(kAcquireLoad)) { 3341cb0ef41Sopenharmony_ci constant = properties.get(array_index); 3351cb0ef41Sopenharmony_ci } else { 3361cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING( 3371cb0ef41Sopenharmony_ci broker, "Backing store for " << holder << " not long enough."); 3381cb0ef41Sopenharmony_ci return {}; 3391cb0ef41Sopenharmony_ci } 3401cb0ef41Sopenharmony_ci } 3411cb0ef41Sopenharmony_ci 3421cb0ef41Sopenharmony_ci // {constant} needs to pass the gc predicate before we can introspect on it. 3431cb0ef41Sopenharmony_ci if (broker->ObjectMayBeUninitialized(constant.value())) return {}; 3441cb0ef41Sopenharmony_ci 3451cb0ef41Sopenharmony_ci // Ensure that {constant} matches the {representation} we expect for the 3461cb0ef41Sopenharmony_ci // field. 3471cb0ef41Sopenharmony_ci if (!constant->FitsRepresentation(representation, false)) { 3481cb0ef41Sopenharmony_ci const char* repString = 3491cb0ef41Sopenharmony_ci constant->IsSmi() 3501cb0ef41Sopenharmony_ci ? "Smi" 3511cb0ef41Sopenharmony_ci : constant->IsHeapNumber() ? "HeapNumber" : "HeapObject"; 3521cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker, "Mismatched representation for " 3531cb0ef41Sopenharmony_ci << holder << ". Expected " 3541cb0ef41Sopenharmony_ci << representation << ", but object is a " 3551cb0ef41Sopenharmony_ci << repString); 3561cb0ef41Sopenharmony_ci return {}; 3571cb0ef41Sopenharmony_ci } 3581cb0ef41Sopenharmony_ci } 3591cb0ef41Sopenharmony_ci 3601cb0ef41Sopenharmony_ci // Now that we can safely inspect the constant, it may need to be wrapped. 3611cb0ef41Sopenharmony_ci Handle<Object> value = broker->CanonicalPersistentHandle(constant.value()); 3621cb0ef41Sopenharmony_ci Handle<Object> possibly_wrapped = Object::WrapForRead<AllocationType::kOld>( 3631cb0ef41Sopenharmony_ci broker->local_isolate_or_isolate(), value, representation); 3641cb0ef41Sopenharmony_ci return TryMakeRef(broker, *possibly_wrapped); 3651cb0ef41Sopenharmony_ci} 3661cb0ef41Sopenharmony_ci 3671cb0ef41Sopenharmony_ci// Tries to get the property at {dict_index}. If we are within bounds of the 3681cb0ef41Sopenharmony_ci// object, we are guaranteed to see valid heap words even if the data is wrong. 3691cb0ef41Sopenharmony_cibase::Optional<ObjectRef> GetOwnDictionaryPropertyFromHeap( 3701cb0ef41Sopenharmony_ci JSHeapBroker* broker, Handle<JSObject> receiver, InternalIndex dict_index) { 3711cb0ef41Sopenharmony_ci Handle<Object> constant; 3721cb0ef41Sopenharmony_ci { 3731cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 3741cb0ef41Sopenharmony_ci // DictionaryPropertyAt will check that we are within the bounds of the 3751cb0ef41Sopenharmony_ci // object. 3761cb0ef41Sopenharmony_ci base::Optional<Object> maybe_constant = JSObject::DictionaryPropertyAt( 3771cb0ef41Sopenharmony_ci receiver, dict_index, broker->isolate()->heap()); 3781cb0ef41Sopenharmony_ci DCHECK_IMPLIES(broker->IsMainThread(), maybe_constant); 3791cb0ef41Sopenharmony_ci if (!maybe_constant) return {}; 3801cb0ef41Sopenharmony_ci constant = broker->CanonicalPersistentHandle(maybe_constant.value()); 3811cb0ef41Sopenharmony_ci } 3821cb0ef41Sopenharmony_ci return TryMakeRef(broker, constant); 3831cb0ef41Sopenharmony_ci} 3841cb0ef41Sopenharmony_ci 3851cb0ef41Sopenharmony_ci} // namespace 3861cb0ef41Sopenharmony_ci 3871cb0ef41Sopenharmony_ciclass JSTypedArrayData : public JSObjectData { 3881cb0ef41Sopenharmony_ci public: 3891cb0ef41Sopenharmony_ci JSTypedArrayData(JSHeapBroker* broker, ObjectData** storage, 3901cb0ef41Sopenharmony_ci Handle<JSTypedArray> object, ObjectDataKind kind) 3911cb0ef41Sopenharmony_ci : JSObjectData(broker, storage, object, kind) {} 3921cb0ef41Sopenharmony_ci}; 3931cb0ef41Sopenharmony_ci 3941cb0ef41Sopenharmony_ciclass JSDataViewData : public JSObjectData { 3951cb0ef41Sopenharmony_ci public: 3961cb0ef41Sopenharmony_ci JSDataViewData(JSHeapBroker* broker, ObjectData** storage, 3971cb0ef41Sopenharmony_ci Handle<JSDataView> object, ObjectDataKind kind) 3981cb0ef41Sopenharmony_ci : JSObjectData(broker, storage, object, kind) {} 3991cb0ef41Sopenharmony_ci}; 4001cb0ef41Sopenharmony_ci 4011cb0ef41Sopenharmony_ciclass JSBoundFunctionData : public JSObjectData { 4021cb0ef41Sopenharmony_ci public: 4031cb0ef41Sopenharmony_ci JSBoundFunctionData(JSHeapBroker* broker, ObjectData** storage, 4041cb0ef41Sopenharmony_ci Handle<JSBoundFunction> object, ObjectDataKind kind) 4051cb0ef41Sopenharmony_ci : JSObjectData(broker, storage, object, kind) {} 4061cb0ef41Sopenharmony_ci}; 4071cb0ef41Sopenharmony_ci 4081cb0ef41Sopenharmony_ciclass JSFunctionData : public JSObjectData { 4091cb0ef41Sopenharmony_ci public: 4101cb0ef41Sopenharmony_ci JSFunctionData(JSHeapBroker* broker, ObjectData** storage, 4111cb0ef41Sopenharmony_ci Handle<JSFunction> object, ObjectDataKind kind) 4121cb0ef41Sopenharmony_ci : JSObjectData(broker, storage, object, kind) { 4131cb0ef41Sopenharmony_ci Cache(broker); 4141cb0ef41Sopenharmony_ci } 4151cb0ef41Sopenharmony_ci 4161cb0ef41Sopenharmony_ci bool IsConsistentWithHeapState(JSHeapBroker* broker) const; 4171cb0ef41Sopenharmony_ci 4181cb0ef41Sopenharmony_ci bool has_initial_map() const { 4191cb0ef41Sopenharmony_ci DCHECK(serialized_); 4201cb0ef41Sopenharmony_ci return has_initial_map_; 4211cb0ef41Sopenharmony_ci } 4221cb0ef41Sopenharmony_ci bool has_instance_prototype() const { 4231cb0ef41Sopenharmony_ci DCHECK(serialized_); 4241cb0ef41Sopenharmony_ci return has_instance_prototype_; 4251cb0ef41Sopenharmony_ci } 4261cb0ef41Sopenharmony_ci bool PrototypeRequiresRuntimeLookup() const { 4271cb0ef41Sopenharmony_ci DCHECK(serialized_); 4281cb0ef41Sopenharmony_ci return PrototypeRequiresRuntimeLookup_; 4291cb0ef41Sopenharmony_ci } 4301cb0ef41Sopenharmony_ci 4311cb0ef41Sopenharmony_ci ObjectData* context() const { 4321cb0ef41Sopenharmony_ci DCHECK(serialized_); 4331cb0ef41Sopenharmony_ci return context_; 4341cb0ef41Sopenharmony_ci } 4351cb0ef41Sopenharmony_ci MapData* initial_map() const { 4361cb0ef41Sopenharmony_ci DCHECK(serialized_); 4371cb0ef41Sopenharmony_ci return initial_map_; 4381cb0ef41Sopenharmony_ci } 4391cb0ef41Sopenharmony_ci ObjectData* instance_prototype() const { 4401cb0ef41Sopenharmony_ci DCHECK(serialized_); 4411cb0ef41Sopenharmony_ci return instance_prototype_; 4421cb0ef41Sopenharmony_ci } 4431cb0ef41Sopenharmony_ci ObjectData* shared() const { 4441cb0ef41Sopenharmony_ci DCHECK(serialized_); 4451cb0ef41Sopenharmony_ci return shared_; 4461cb0ef41Sopenharmony_ci } 4471cb0ef41Sopenharmony_ci ObjectData* raw_feedback_cell() const { 4481cb0ef41Sopenharmony_ci DCHECK(serialized_); 4491cb0ef41Sopenharmony_ci return feedback_cell_; 4501cb0ef41Sopenharmony_ci } 4511cb0ef41Sopenharmony_ci int initial_map_instance_size_with_min_slack() const { 4521cb0ef41Sopenharmony_ci DCHECK(serialized_); 4531cb0ef41Sopenharmony_ci return initial_map_instance_size_with_min_slack_; 4541cb0ef41Sopenharmony_ci } 4551cb0ef41Sopenharmony_ci 4561cb0ef41Sopenharmony_ci // Track serialized fields that are actually used, in order to relax 4571cb0ef41Sopenharmony_ci // ConsistentJSFunctionView dependency validation as much as possible. 4581cb0ef41Sopenharmony_ci enum UsedField { 4591cb0ef41Sopenharmony_ci kHasFeedbackVector = 1 << 0, 4601cb0ef41Sopenharmony_ci kPrototypeOrInitialMap = 1 << 1, 4611cb0ef41Sopenharmony_ci kHasInitialMap = 1 << 2, 4621cb0ef41Sopenharmony_ci kHasInstancePrototype = 1 << 3, 4631cb0ef41Sopenharmony_ci kPrototypeRequiresRuntimeLookup = 1 << 4, 4641cb0ef41Sopenharmony_ci kInitialMap = 1 << 5, 4651cb0ef41Sopenharmony_ci kInstancePrototype = 1 << 6, 4661cb0ef41Sopenharmony_ci kFeedbackVector = 1 << 7, 4671cb0ef41Sopenharmony_ci kFeedbackCell = 1 << 8, 4681cb0ef41Sopenharmony_ci kInitialMapInstanceSizeWithMinSlack = 1 << 9, 4691cb0ef41Sopenharmony_ci }; 4701cb0ef41Sopenharmony_ci 4711cb0ef41Sopenharmony_ci bool has_any_used_field() const { return used_fields_ != 0; } 4721cb0ef41Sopenharmony_ci bool has_used_field(UsedField used_field) const { 4731cb0ef41Sopenharmony_ci return (used_fields_ & used_field) != 0; 4741cb0ef41Sopenharmony_ci } 4751cb0ef41Sopenharmony_ci void set_used_field(UsedField used_field) { used_fields_ |= used_field; } 4761cb0ef41Sopenharmony_ci 4771cb0ef41Sopenharmony_ci private: 4781cb0ef41Sopenharmony_ci void Cache(JSHeapBroker* broker); 4791cb0ef41Sopenharmony_ci 4801cb0ef41Sopenharmony_ci#ifdef DEBUG 4811cb0ef41Sopenharmony_ci bool serialized_ = false; 4821cb0ef41Sopenharmony_ci#endif // DEBUG 4831cb0ef41Sopenharmony_ci 4841cb0ef41Sopenharmony_ci using UsedFields = base::Flags<UsedField>; 4851cb0ef41Sopenharmony_ci UsedFields used_fields_; 4861cb0ef41Sopenharmony_ci 4871cb0ef41Sopenharmony_ci ObjectData* prototype_or_initial_map_ = nullptr; 4881cb0ef41Sopenharmony_ci bool has_initial_map_ = false; 4891cb0ef41Sopenharmony_ci bool has_instance_prototype_ = false; 4901cb0ef41Sopenharmony_ci bool PrototypeRequiresRuntimeLookup_ = false; 4911cb0ef41Sopenharmony_ci 4921cb0ef41Sopenharmony_ci ObjectData* context_ = nullptr; 4931cb0ef41Sopenharmony_ci MapData* initial_map_ = nullptr; // Derives from prototype_or_initial_map_. 4941cb0ef41Sopenharmony_ci ObjectData* instance_prototype_ = 4951cb0ef41Sopenharmony_ci nullptr; // Derives from prototype_or_initial_map_. 4961cb0ef41Sopenharmony_ci ObjectData* shared_ = nullptr; 4971cb0ef41Sopenharmony_ci ObjectData* feedback_cell_ = nullptr; 4981cb0ef41Sopenharmony_ci int initial_map_instance_size_with_min_slack_; // Derives from 4991cb0ef41Sopenharmony_ci // prototype_or_initial_map_. 5001cb0ef41Sopenharmony_ci}; 5011cb0ef41Sopenharmony_ci 5021cb0ef41Sopenharmony_ciclass BigIntData : public HeapObjectData { 5031cb0ef41Sopenharmony_ci public: 5041cb0ef41Sopenharmony_ci BigIntData(JSHeapBroker* broker, ObjectData** storage, Handle<BigInt> object, 5051cb0ef41Sopenharmony_ci ObjectDataKind kind) 5061cb0ef41Sopenharmony_ci : HeapObjectData(broker, storage, object, kind), 5071cb0ef41Sopenharmony_ci as_uint64_(object->AsUint64(nullptr)) {} 5081cb0ef41Sopenharmony_ci 5091cb0ef41Sopenharmony_ci uint64_t AsUint64() const { return as_uint64_; } 5101cb0ef41Sopenharmony_ci 5111cb0ef41Sopenharmony_ci private: 5121cb0ef41Sopenharmony_ci const uint64_t as_uint64_; 5131cb0ef41Sopenharmony_ci}; 5141cb0ef41Sopenharmony_ci 5151cb0ef41Sopenharmony_cistruct PropertyDescriptor { 5161cb0ef41Sopenharmony_ci FieldIndex field_index; 5171cb0ef41Sopenharmony_ci ObjectData* field_owner = nullptr; 5181cb0ef41Sopenharmony_ci}; 5191cb0ef41Sopenharmony_ci 5201cb0ef41Sopenharmony_ciclass MapData : public HeapObjectData { 5211cb0ef41Sopenharmony_ci public: 5221cb0ef41Sopenharmony_ci MapData(JSHeapBroker* broker, ObjectData** storage, Handle<Map> object, 5231cb0ef41Sopenharmony_ci ObjectDataKind kind); 5241cb0ef41Sopenharmony_ci 5251cb0ef41Sopenharmony_ci InstanceType instance_type() const { return instance_type_; } 5261cb0ef41Sopenharmony_ci int instance_size() const { return instance_size_; } 5271cb0ef41Sopenharmony_ci uint32_t bit_field3() const { return bit_field3_; } 5281cb0ef41Sopenharmony_ci int in_object_properties() const { 5291cb0ef41Sopenharmony_ci CHECK(InstanceTypeChecker::IsJSObject(instance_type())); 5301cb0ef41Sopenharmony_ci return in_object_properties_; 5311cb0ef41Sopenharmony_ci } 5321cb0ef41Sopenharmony_ci int UnusedPropertyFields() const { return unused_property_fields_; } 5331cb0ef41Sopenharmony_ci bool is_abandoned_prototype_map() const { 5341cb0ef41Sopenharmony_ci return is_abandoned_prototype_map_; 5351cb0ef41Sopenharmony_ci } 5361cb0ef41Sopenharmony_ci 5371cb0ef41Sopenharmony_ci private: 5381cb0ef41Sopenharmony_ci // The following fields should be const in principle, but construction 5391cb0ef41Sopenharmony_ci // requires locking the MapUpdater lock. For this reason, it's easier to 5401cb0ef41Sopenharmony_ci // initialize these inside the constructor body, not in the initializer list. 5411cb0ef41Sopenharmony_ci 5421cb0ef41Sopenharmony_ci InstanceType instance_type_; 5431cb0ef41Sopenharmony_ci int instance_size_; 5441cb0ef41Sopenharmony_ci uint32_t bit_field3_; 5451cb0ef41Sopenharmony_ci int unused_property_fields_; 5461cb0ef41Sopenharmony_ci bool is_abandoned_prototype_map_; 5471cb0ef41Sopenharmony_ci int in_object_properties_; 5481cb0ef41Sopenharmony_ci}; 5491cb0ef41Sopenharmony_ci 5501cb0ef41Sopenharmony_cinamespace { 5511cb0ef41Sopenharmony_ci 5521cb0ef41Sopenharmony_ciint InstanceSizeWithMinSlack(JSHeapBroker* broker, MapRef map) { 5531cb0ef41Sopenharmony_ci // This operation is split into two phases (1. map collection, 2. map 5541cb0ef41Sopenharmony_ci // processing). This is to avoid having to take two locks 5551cb0ef41Sopenharmony_ci // (full_transition_array_access and map_updater_access) at once and thus 5561cb0ef41Sopenharmony_ci // having to deal with related deadlock issues. 5571cb0ef41Sopenharmony_ci ZoneVector<Handle<Map>> maps(broker->zone()); 5581cb0ef41Sopenharmony_ci maps.push_back(map.object()); 5591cb0ef41Sopenharmony_ci 5601cb0ef41Sopenharmony_ci { 5611cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 5621cb0ef41Sopenharmony_ci 5631cb0ef41Sopenharmony_ci // Has to be an initial map. 5641cb0ef41Sopenharmony_ci DCHECK(map.object()->GetBackPointer().IsUndefined(broker->isolate())); 5651cb0ef41Sopenharmony_ci 5661cb0ef41Sopenharmony_ci static constexpr bool kConcurrentAccess = true; 5671cb0ef41Sopenharmony_ci TransitionsAccessor(broker->isolate(), *map.object(), kConcurrentAccess) 5681cb0ef41Sopenharmony_ci .TraverseTransitionTree([&](Map m) { 5691cb0ef41Sopenharmony_ci maps.push_back(broker->CanonicalPersistentHandle(m)); 5701cb0ef41Sopenharmony_ci }); 5711cb0ef41Sopenharmony_ci } 5721cb0ef41Sopenharmony_ci 5731cb0ef41Sopenharmony_ci // The lock is needed for UnusedPropertyFields and InstanceSizeFromSlack. 5741cb0ef41Sopenharmony_ci JSHeapBroker::MapUpdaterGuardIfNeeded mumd_scope(broker); 5751cb0ef41Sopenharmony_ci 5761cb0ef41Sopenharmony_ci int slack = std::numeric_limits<int>::max(); 5771cb0ef41Sopenharmony_ci for (Handle<Map> m : maps) { 5781cb0ef41Sopenharmony_ci slack = std::min(slack, m->UnusedPropertyFields()); 5791cb0ef41Sopenharmony_ci } 5801cb0ef41Sopenharmony_ci 5811cb0ef41Sopenharmony_ci return map.object()->InstanceSizeFromSlack(slack); 5821cb0ef41Sopenharmony_ci} 5831cb0ef41Sopenharmony_ci 5841cb0ef41Sopenharmony_ci} // namespace 5851cb0ef41Sopenharmony_ci 5861cb0ef41Sopenharmony_ci// IMPORTANT: Keep this sync'd with JSFunctionData::IsConsistentWithHeapState. 5871cb0ef41Sopenharmony_civoid JSFunctionData::Cache(JSHeapBroker* broker) { 5881cb0ef41Sopenharmony_ci DCHECK(!serialized_); 5891cb0ef41Sopenharmony_ci 5901cb0ef41Sopenharmony_ci TraceScope tracer(broker, this, "JSFunctionData::Cache"); 5911cb0ef41Sopenharmony_ci Handle<JSFunction> function = Handle<JSFunction>::cast(object()); 5921cb0ef41Sopenharmony_ci 5931cb0ef41Sopenharmony_ci // This function may run on the background thread and thus must be individual 5941cb0ef41Sopenharmony_ci // fields in a thread-safe manner. Consistency between fields is *not* 5951cb0ef41Sopenharmony_ci // guaranteed here, instead we verify it in `IsConsistentWithHeapState`, 5961cb0ef41Sopenharmony_ci // called during job finalization. Relaxed loads are thus okay: we're 5971cb0ef41Sopenharmony_ci // guaranteed to see an initialized JSFunction object, and after 5981cb0ef41Sopenharmony_ci // initialization fields remain in a valid state. 5991cb0ef41Sopenharmony_ci 6001cb0ef41Sopenharmony_ci ContextRef context = 6011cb0ef41Sopenharmony_ci MakeRefAssumeMemoryFence(broker, function->context(kRelaxedLoad)); 6021cb0ef41Sopenharmony_ci context_ = context.data(); 6031cb0ef41Sopenharmony_ci 6041cb0ef41Sopenharmony_ci SharedFunctionInfoRef shared = 6051cb0ef41Sopenharmony_ci MakeRefAssumeMemoryFence(broker, function->shared(kRelaxedLoad)); 6061cb0ef41Sopenharmony_ci shared_ = shared.data(); 6071cb0ef41Sopenharmony_ci 6081cb0ef41Sopenharmony_ci if (function->has_prototype_slot()) { 6091cb0ef41Sopenharmony_ci prototype_or_initial_map_ = broker->GetOrCreateData( 6101cb0ef41Sopenharmony_ci function->prototype_or_initial_map(kAcquireLoad), kAssumeMemoryFence); 6111cb0ef41Sopenharmony_ci 6121cb0ef41Sopenharmony_ci has_initial_map_ = prototype_or_initial_map_->IsMap(); 6131cb0ef41Sopenharmony_ci if (has_initial_map_) { 6141cb0ef41Sopenharmony_ci initial_map_ = prototype_or_initial_map_->AsMap(); 6151cb0ef41Sopenharmony_ci 6161cb0ef41Sopenharmony_ci MapRef initial_map_ref = TryMakeRef<Map>(broker, initial_map_).value(); 6171cb0ef41Sopenharmony_ci if (initial_map_ref.IsInobjectSlackTrackingInProgress()) { 6181cb0ef41Sopenharmony_ci initial_map_instance_size_with_min_slack_ = 6191cb0ef41Sopenharmony_ci InstanceSizeWithMinSlack(broker, initial_map_ref); 6201cb0ef41Sopenharmony_ci } else { 6211cb0ef41Sopenharmony_ci initial_map_instance_size_with_min_slack_ = 6221cb0ef41Sopenharmony_ci initial_map_ref.instance_size(); 6231cb0ef41Sopenharmony_ci } 6241cb0ef41Sopenharmony_ci CHECK_GT(initial_map_instance_size_with_min_slack_, 0); 6251cb0ef41Sopenharmony_ci } 6261cb0ef41Sopenharmony_ci 6271cb0ef41Sopenharmony_ci if (has_initial_map_) { 6281cb0ef41Sopenharmony_ci has_instance_prototype_ = true; 6291cb0ef41Sopenharmony_ci instance_prototype_ = 6301cb0ef41Sopenharmony_ci MakeRefAssumeMemoryFence( 6311cb0ef41Sopenharmony_ci broker, Handle<Map>::cast(initial_map_->object())->prototype()) 6321cb0ef41Sopenharmony_ci .data(); 6331cb0ef41Sopenharmony_ci } else if (prototype_or_initial_map_->IsHeapObject() && 6341cb0ef41Sopenharmony_ci !Handle<HeapObject>::cast(prototype_or_initial_map_->object()) 6351cb0ef41Sopenharmony_ci ->IsTheHole()) { 6361cb0ef41Sopenharmony_ci has_instance_prototype_ = true; 6371cb0ef41Sopenharmony_ci instance_prototype_ = prototype_or_initial_map_; 6381cb0ef41Sopenharmony_ci } 6391cb0ef41Sopenharmony_ci } 6401cb0ef41Sopenharmony_ci 6411cb0ef41Sopenharmony_ci PrototypeRequiresRuntimeLookup_ = function->PrototypeRequiresRuntimeLookup(); 6421cb0ef41Sopenharmony_ci 6431cb0ef41Sopenharmony_ci FeedbackCellRef feedback_cell = MakeRefAssumeMemoryFence( 6441cb0ef41Sopenharmony_ci broker, function->raw_feedback_cell(kAcquireLoad)); 6451cb0ef41Sopenharmony_ci feedback_cell_ = feedback_cell.data(); 6461cb0ef41Sopenharmony_ci 6471cb0ef41Sopenharmony_ci#ifdef DEBUG 6481cb0ef41Sopenharmony_ci serialized_ = true; 6491cb0ef41Sopenharmony_ci#endif // DEBUG 6501cb0ef41Sopenharmony_ci} 6511cb0ef41Sopenharmony_ci 6521cb0ef41Sopenharmony_ci// IMPORTANT: Keep this sync'd with JSFunctionData::Cache. 6531cb0ef41Sopenharmony_cibool JSFunctionData::IsConsistentWithHeapState(JSHeapBroker* broker) const { 6541cb0ef41Sopenharmony_ci DCHECK(serialized_); 6551cb0ef41Sopenharmony_ci 6561cb0ef41Sopenharmony_ci Handle<JSFunction> f = Handle<JSFunction>::cast(object()); 6571cb0ef41Sopenharmony_ci 6581cb0ef41Sopenharmony_ci CHECK_EQ(*context_->object(), f->context()); 6591cb0ef41Sopenharmony_ci CHECK_EQ(*shared_->object(), f->shared()); 6601cb0ef41Sopenharmony_ci 6611cb0ef41Sopenharmony_ci if (f->has_prototype_slot()) { 6621cb0ef41Sopenharmony_ci if (has_used_field(kPrototypeOrInitialMap) && 6631cb0ef41Sopenharmony_ci *prototype_or_initial_map_->object() != 6641cb0ef41Sopenharmony_ci f->prototype_or_initial_map(kAcquireLoad)) { 6651cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker, "JSFunction::prototype_or_initial_map"); 6661cb0ef41Sopenharmony_ci return false; 6671cb0ef41Sopenharmony_ci } 6681cb0ef41Sopenharmony_ci if (has_used_field(kHasInitialMap) && 6691cb0ef41Sopenharmony_ci has_initial_map_ != f->has_initial_map()) { 6701cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker, "JSFunction::has_initial_map"); 6711cb0ef41Sopenharmony_ci return false; 6721cb0ef41Sopenharmony_ci } 6731cb0ef41Sopenharmony_ci if (has_used_field(kHasInstancePrototype) && 6741cb0ef41Sopenharmony_ci has_instance_prototype_ != f->has_instance_prototype()) { 6751cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker, "JSFunction::has_instance_prototype"); 6761cb0ef41Sopenharmony_ci return false; 6771cb0ef41Sopenharmony_ci } 6781cb0ef41Sopenharmony_ci } else { 6791cb0ef41Sopenharmony_ci DCHECK(!has_initial_map_); 6801cb0ef41Sopenharmony_ci DCHECK(!has_instance_prototype_); 6811cb0ef41Sopenharmony_ci } 6821cb0ef41Sopenharmony_ci 6831cb0ef41Sopenharmony_ci if (has_initial_map()) { 6841cb0ef41Sopenharmony_ci if (has_used_field(kInitialMap) && 6851cb0ef41Sopenharmony_ci *initial_map_->object() != f->initial_map()) { 6861cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker, "JSFunction::initial_map"); 6871cb0ef41Sopenharmony_ci return false; 6881cb0ef41Sopenharmony_ci } 6891cb0ef41Sopenharmony_ci if (has_used_field(kInitialMapInstanceSizeWithMinSlack) && 6901cb0ef41Sopenharmony_ci initial_map_instance_size_with_min_slack_ != 6911cb0ef41Sopenharmony_ci f->ComputeInstanceSizeWithMinSlack(f->GetIsolate())) { 6921cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker, 6931cb0ef41Sopenharmony_ci "JSFunction::ComputeInstanceSizeWithMinSlack"); 6941cb0ef41Sopenharmony_ci return false; 6951cb0ef41Sopenharmony_ci } 6961cb0ef41Sopenharmony_ci } else { 6971cb0ef41Sopenharmony_ci DCHECK_NULL(initial_map_); 6981cb0ef41Sopenharmony_ci } 6991cb0ef41Sopenharmony_ci 7001cb0ef41Sopenharmony_ci if (has_instance_prototype_) { 7011cb0ef41Sopenharmony_ci if (has_used_field(kInstancePrototype) && 7021cb0ef41Sopenharmony_ci *instance_prototype_->object() != f->instance_prototype()) { 7031cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker, "JSFunction::instance_prototype"); 7041cb0ef41Sopenharmony_ci return false; 7051cb0ef41Sopenharmony_ci } 7061cb0ef41Sopenharmony_ci } else { 7071cb0ef41Sopenharmony_ci DCHECK_NULL(instance_prototype_); 7081cb0ef41Sopenharmony_ci } 7091cb0ef41Sopenharmony_ci 7101cb0ef41Sopenharmony_ci if (has_used_field(kPrototypeRequiresRuntimeLookup) && 7111cb0ef41Sopenharmony_ci PrototypeRequiresRuntimeLookup_ != f->PrototypeRequiresRuntimeLookup()) { 7121cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker, "JSFunction::PrototypeRequiresRuntimeLookup"); 7131cb0ef41Sopenharmony_ci return false; 7141cb0ef41Sopenharmony_ci } 7151cb0ef41Sopenharmony_ci 7161cb0ef41Sopenharmony_ci if (has_used_field(kFeedbackCell) && 7171cb0ef41Sopenharmony_ci *feedback_cell_->object() != f->raw_feedback_cell()) { 7181cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker, "JSFunction::raw_feedback_cell"); 7191cb0ef41Sopenharmony_ci return false; 7201cb0ef41Sopenharmony_ci } 7211cb0ef41Sopenharmony_ci 7221cb0ef41Sopenharmony_ci return true; 7231cb0ef41Sopenharmony_ci} 7241cb0ef41Sopenharmony_ci 7251cb0ef41Sopenharmony_cibool JSFunctionRef::IsConsistentWithHeapState() const { 7261cb0ef41Sopenharmony_ci DCHECK(broker()->IsMainThread()); 7271cb0ef41Sopenharmony_ci return data()->AsJSFunction()->IsConsistentWithHeapState(broker()); 7281cb0ef41Sopenharmony_ci} 7291cb0ef41Sopenharmony_ci 7301cb0ef41Sopenharmony_ciHeapObjectData::HeapObjectData(JSHeapBroker* broker, ObjectData** storage, 7311cb0ef41Sopenharmony_ci Handle<HeapObject> object, ObjectDataKind kind) 7321cb0ef41Sopenharmony_ci : ObjectData(broker, storage, object, kind), 7331cb0ef41Sopenharmony_ci map_(broker->GetOrCreateData( 7341cb0ef41Sopenharmony_ci object->map(broker->cage_base(), kAcquireLoad), kAssumeMemoryFence)) { 7351cb0ef41Sopenharmony_ci CHECK_IMPLIES(broker->mode() == JSHeapBroker::kSerialized, 7361cb0ef41Sopenharmony_ci kind == kBackgroundSerializedHeapObject); 7371cb0ef41Sopenharmony_ci} 7381cb0ef41Sopenharmony_ci 7391cb0ef41Sopenharmony_cibase::Optional<bool> HeapObjectData::TryGetBooleanValue( 7401cb0ef41Sopenharmony_ci JSHeapBroker* broker) const { 7411cb0ef41Sopenharmony_ci // Keep in sync with Object::BooleanValue. 7421cb0ef41Sopenharmony_ci auto result = TryGetBooleanValueImpl(broker); 7431cb0ef41Sopenharmony_ci DCHECK_IMPLIES(broker->IsMainThread() && result.has_value(), 7441cb0ef41Sopenharmony_ci result.value() == object()->BooleanValue(broker->isolate())); 7451cb0ef41Sopenharmony_ci return result; 7461cb0ef41Sopenharmony_ci} 7471cb0ef41Sopenharmony_ci 7481cb0ef41Sopenharmony_cibase::Optional<bool> HeapObjectData::TryGetBooleanValueImpl( 7491cb0ef41Sopenharmony_ci JSHeapBroker* broker) const { 7501cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 7511cb0ef41Sopenharmony_ci Object o = *object(); 7521cb0ef41Sopenharmony_ci Isolate* isolate = broker->isolate(); 7531cb0ef41Sopenharmony_ci const InstanceType t = GetMapInstanceType(); 7541cb0ef41Sopenharmony_ci if (o.IsTrue(isolate)) { 7551cb0ef41Sopenharmony_ci return true; 7561cb0ef41Sopenharmony_ci } else if (o.IsFalse(isolate)) { 7571cb0ef41Sopenharmony_ci return false; 7581cb0ef41Sopenharmony_ci } else if (o.IsNullOrUndefined(isolate)) { 7591cb0ef41Sopenharmony_ci return false; 7601cb0ef41Sopenharmony_ci } else if (MapRef{broker, map()}.is_undetectable()) { 7611cb0ef41Sopenharmony_ci return false; // Undetectable object is false. 7621cb0ef41Sopenharmony_ci } else if (InstanceTypeChecker::IsString(t)) { 7631cb0ef41Sopenharmony_ci // TODO(jgruber): Implement in possible cases. 7641cb0ef41Sopenharmony_ci return {}; 7651cb0ef41Sopenharmony_ci } else if (InstanceTypeChecker::IsHeapNumber(t)) { 7661cb0ef41Sopenharmony_ci return {}; 7671cb0ef41Sopenharmony_ci } else if (InstanceTypeChecker::IsBigInt(t)) { 7681cb0ef41Sopenharmony_ci return {}; 7691cb0ef41Sopenharmony_ci } 7701cb0ef41Sopenharmony_ci return true; 7711cb0ef41Sopenharmony_ci} 7721cb0ef41Sopenharmony_ci 7731cb0ef41Sopenharmony_ciInstanceType HeapObjectData::GetMapInstanceType() const { 7741cb0ef41Sopenharmony_ci ObjectData* map_data = map(); 7751cb0ef41Sopenharmony_ci if (map_data->should_access_heap()) { 7761cb0ef41Sopenharmony_ci return Handle<Map>::cast(map_data->object())->instance_type(); 7771cb0ef41Sopenharmony_ci } 7781cb0ef41Sopenharmony_ci return map_data->AsMap()->instance_type(); 7791cb0ef41Sopenharmony_ci} 7801cb0ef41Sopenharmony_ci 7811cb0ef41Sopenharmony_cinamespace { 7821cb0ef41Sopenharmony_ci 7831cb0ef41Sopenharmony_cibool IsReadOnlyLengthDescriptor(Isolate* isolate, Handle<Map> jsarray_map) { 7841cb0ef41Sopenharmony_ci DCHECK(!jsarray_map->is_dictionary_map()); 7851cb0ef41Sopenharmony_ci DescriptorArray descriptors = 7861cb0ef41Sopenharmony_ci jsarray_map->instance_descriptors(isolate, kRelaxedLoad); 7871cb0ef41Sopenharmony_ci static_assert( 7881cb0ef41Sopenharmony_ci JSArray::kLengthOffset == JSObject::kHeaderSize, 7891cb0ef41Sopenharmony_ci "The length should be the first property on the descriptor array"); 7901cb0ef41Sopenharmony_ci InternalIndex offset(0); 7911cb0ef41Sopenharmony_ci return descriptors.GetDetails(offset).IsReadOnly(); 7921cb0ef41Sopenharmony_ci} 7931cb0ef41Sopenharmony_ci 7941cb0ef41Sopenharmony_ci// Important: this predicate does not check Protectors::IsNoElementsIntact. The 7951cb0ef41Sopenharmony_ci// compiler checks protectors through the compilation dependency mechanism; it 7961cb0ef41Sopenharmony_ci// doesn't make sense to do that here as part of every MapData construction. 7971cb0ef41Sopenharmony_ci// Callers *must* take care to take the correct dependency themselves. 7981cb0ef41Sopenharmony_cibool SupportsFastArrayIteration(JSHeapBroker* broker, Handle<Map> map) { 7991cb0ef41Sopenharmony_ci return map->instance_type() == JS_ARRAY_TYPE && 8001cb0ef41Sopenharmony_ci IsFastElementsKind(map->elements_kind()) && 8011cb0ef41Sopenharmony_ci map->prototype().IsJSArray() && 8021cb0ef41Sopenharmony_ci broker->IsArrayOrObjectPrototype(broker->CanonicalPersistentHandle( 8031cb0ef41Sopenharmony_ci JSArray::cast(map->prototype()))); 8041cb0ef41Sopenharmony_ci} 8051cb0ef41Sopenharmony_ci 8061cb0ef41Sopenharmony_cibool SupportsFastArrayResize(JSHeapBroker* broker, Handle<Map> map) { 8071cb0ef41Sopenharmony_ci return SupportsFastArrayIteration(broker, map) && map->is_extensible() && 8081cb0ef41Sopenharmony_ci !map->is_dictionary_map() && 8091cb0ef41Sopenharmony_ci !IsReadOnlyLengthDescriptor(broker->isolate(), map); 8101cb0ef41Sopenharmony_ci} 8111cb0ef41Sopenharmony_ci 8121cb0ef41Sopenharmony_ci} // namespace 8131cb0ef41Sopenharmony_ci 8141cb0ef41Sopenharmony_ciMapData::MapData(JSHeapBroker* broker, ObjectData** storage, Handle<Map> object, 8151cb0ef41Sopenharmony_ci ObjectDataKind kind) 8161cb0ef41Sopenharmony_ci : HeapObjectData(broker, storage, object, kind) { 8171cb0ef41Sopenharmony_ci // This lock ensure that MapData can always be background-serialized, i.e. 8181cb0ef41Sopenharmony_ci // while the lock is held the Map object may not be modified (except in 8191cb0ef41Sopenharmony_ci // benign ways). 8201cb0ef41Sopenharmony_ci // TODO(jgruber): Consider removing this lock by being smrt. 8211cb0ef41Sopenharmony_ci JSHeapBroker::MapUpdaterGuardIfNeeded mumd_scope(broker); 8221cb0ef41Sopenharmony_ci 8231cb0ef41Sopenharmony_ci // When background serializing the map, we can perform a lite serialization 8241cb0ef41Sopenharmony_ci // since the MapRef will read some of the Map's fields can be read directly. 8251cb0ef41Sopenharmony_ci 8261cb0ef41Sopenharmony_ci // Even though MapRefs can read {instance_type} directly, other classes depend 8271cb0ef41Sopenharmony_ci // on {instance_type} being serialized. 8281cb0ef41Sopenharmony_ci instance_type_ = object->instance_type(); 8291cb0ef41Sopenharmony_ci instance_size_ = object->instance_size(); 8301cb0ef41Sopenharmony_ci 8311cb0ef41Sopenharmony_ci // Both bit_field3 (and below bit_field) are special fields: Even though most 8321cb0ef41Sopenharmony_ci // of the individual bits inside of the bitfield could be read / written 8331cb0ef41Sopenharmony_ci // non-atomically, the bitfield itself has to use atomic relaxed accessors 8341cb0ef41Sopenharmony_ci // since some fields since can be modified in live objects. 8351cb0ef41Sopenharmony_ci // TODO(solanes, v8:7790): Assess if adding the exclusive lock in more places 8361cb0ef41Sopenharmony_ci // (e.g for set_has_non_instance_prototype) makes sense. Pros: these fields 8371cb0ef41Sopenharmony_ci // can use the non-atomic accessors. Cons: We would be acquiring an exclusive 8381cb0ef41Sopenharmony_ci // lock in more places. 8391cb0ef41Sopenharmony_ci bit_field3_ = object->relaxed_bit_field3(); 8401cb0ef41Sopenharmony_ci unused_property_fields_ = object->UnusedPropertyFields(); 8411cb0ef41Sopenharmony_ci is_abandoned_prototype_map_ = object->is_abandoned_prototype_map(); 8421cb0ef41Sopenharmony_ci in_object_properties_ = 8431cb0ef41Sopenharmony_ci object->IsJSObjectMap() ? object->GetInObjectProperties() : 0; 8441cb0ef41Sopenharmony_ci} 8451cb0ef41Sopenharmony_ci 8461cb0ef41Sopenharmony_ciclass FixedArrayBaseData : public HeapObjectData { 8471cb0ef41Sopenharmony_ci public: 8481cb0ef41Sopenharmony_ci FixedArrayBaseData(JSHeapBroker* broker, ObjectData** storage, 8491cb0ef41Sopenharmony_ci Handle<FixedArrayBase> object, ObjectDataKind kind) 8501cb0ef41Sopenharmony_ci : HeapObjectData(broker, storage, object, kind), 8511cb0ef41Sopenharmony_ci length_(object->length(kAcquireLoad)) {} 8521cb0ef41Sopenharmony_ci 8531cb0ef41Sopenharmony_ci int length() const { return length_; } 8541cb0ef41Sopenharmony_ci 8551cb0ef41Sopenharmony_ci private: 8561cb0ef41Sopenharmony_ci int const length_; 8571cb0ef41Sopenharmony_ci}; 8581cb0ef41Sopenharmony_ci 8591cb0ef41Sopenharmony_ciclass FixedArrayData : public FixedArrayBaseData { 8601cb0ef41Sopenharmony_ci public: 8611cb0ef41Sopenharmony_ci FixedArrayData(JSHeapBroker* broker, ObjectData** storage, 8621cb0ef41Sopenharmony_ci Handle<FixedArray> object, ObjectDataKind kind) 8631cb0ef41Sopenharmony_ci : FixedArrayBaseData(broker, storage, object, kind) {} 8641cb0ef41Sopenharmony_ci}; 8651cb0ef41Sopenharmony_ci 8661cb0ef41Sopenharmony_ci// Only used in JSNativeContextSpecialization. 8671cb0ef41Sopenharmony_ciclass ScriptContextTableData : public FixedArrayData { 8681cb0ef41Sopenharmony_ci public: 8691cb0ef41Sopenharmony_ci ScriptContextTableData(JSHeapBroker* broker, ObjectData** storage, 8701cb0ef41Sopenharmony_ci Handle<ScriptContextTable> object, ObjectDataKind kind) 8711cb0ef41Sopenharmony_ci : FixedArrayData(broker, storage, object, kind) {} 8721cb0ef41Sopenharmony_ci}; 8731cb0ef41Sopenharmony_ci 8741cb0ef41Sopenharmony_ciclass JSArrayData : public JSObjectData { 8751cb0ef41Sopenharmony_ci public: 8761cb0ef41Sopenharmony_ci JSArrayData(JSHeapBroker* broker, ObjectData** storage, 8771cb0ef41Sopenharmony_ci Handle<JSArray> object, ObjectDataKind kind) 8781cb0ef41Sopenharmony_ci : JSObjectData(broker, storage, object, kind) {} 8791cb0ef41Sopenharmony_ci}; 8801cb0ef41Sopenharmony_ci 8811cb0ef41Sopenharmony_ciclass JSGlobalObjectData : public JSObjectData { 8821cb0ef41Sopenharmony_ci public: 8831cb0ef41Sopenharmony_ci JSGlobalObjectData(JSHeapBroker* broker, ObjectData** storage, 8841cb0ef41Sopenharmony_ci Handle<JSGlobalObject> object, ObjectDataKind kind) 8851cb0ef41Sopenharmony_ci : JSObjectData(broker, storage, object, kind) {} 8861cb0ef41Sopenharmony_ci}; 8871cb0ef41Sopenharmony_ci 8881cb0ef41Sopenharmony_ciclass JSGlobalProxyData : public JSObjectData { 8891cb0ef41Sopenharmony_ci public: 8901cb0ef41Sopenharmony_ci JSGlobalProxyData(JSHeapBroker* broker, ObjectData** storage, 8911cb0ef41Sopenharmony_ci Handle<JSGlobalProxy> object, ObjectDataKind kind) 8921cb0ef41Sopenharmony_ci : JSObjectData(broker, storage, object, kind) {} 8931cb0ef41Sopenharmony_ci}; 8941cb0ef41Sopenharmony_ci 8951cb0ef41Sopenharmony_ci#define DEFINE_IS(Name) \ 8961cb0ef41Sopenharmony_ci bool ObjectData::Is##Name() const { \ 8971cb0ef41Sopenharmony_ci if (should_access_heap()) { \ 8981cb0ef41Sopenharmony_ci return object()->Is##Name(); \ 8991cb0ef41Sopenharmony_ci } \ 9001cb0ef41Sopenharmony_ci if (is_smi()) return false; \ 9011cb0ef41Sopenharmony_ci InstanceType instance_type = \ 9021cb0ef41Sopenharmony_ci static_cast<const HeapObjectData*>(this)->GetMapInstanceType(); \ 9031cb0ef41Sopenharmony_ci return InstanceTypeChecker::Is##Name(instance_type); \ 9041cb0ef41Sopenharmony_ci } 9051cb0ef41Sopenharmony_ciHEAP_BROKER_OBJECT_LIST(DEFINE_IS) 9061cb0ef41Sopenharmony_ci#undef DEFINE_IS 9071cb0ef41Sopenharmony_ci 9081cb0ef41Sopenharmony_ci#define DEFINE_AS(Name) \ 9091cb0ef41Sopenharmony_ci Name##Data* ObjectData::As##Name() { \ 9101cb0ef41Sopenharmony_ci CHECK(Is##Name()); \ 9111cb0ef41Sopenharmony_ci CHECK(kind_ == kBackgroundSerializedHeapObject); \ 9121cb0ef41Sopenharmony_ci return static_cast<Name##Data*>(this); \ 9131cb0ef41Sopenharmony_ci } 9141cb0ef41Sopenharmony_ciHEAP_BROKER_BACKGROUND_SERIALIZED_OBJECT_LIST(DEFINE_AS) 9151cb0ef41Sopenharmony_ci#undef DEFINE_AS 9161cb0ef41Sopenharmony_ci 9171cb0ef41Sopenharmony_cibool ObjectRef::equals(const ObjectRef& other) const { 9181cb0ef41Sopenharmony_ci return data_ == other.data_; 9191cb0ef41Sopenharmony_ci} 9201cb0ef41Sopenharmony_ci 9211cb0ef41Sopenharmony_ciIsolate* ObjectRef::isolate() const { return broker()->isolate(); } 9221cb0ef41Sopenharmony_ci 9231cb0ef41Sopenharmony_ciContextRef ContextRef::previous(size_t* depth) const { 9241cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(depth); 9251cb0ef41Sopenharmony_ci 9261cb0ef41Sopenharmony_ci Context current = *object(); 9271cb0ef41Sopenharmony_ci while (*depth != 0 && current.unchecked_previous().IsContext()) { 9281cb0ef41Sopenharmony_ci current = Context::cast(current.unchecked_previous()); 9291cb0ef41Sopenharmony_ci (*depth)--; 9301cb0ef41Sopenharmony_ci } 9311cb0ef41Sopenharmony_ci // The `previous` field is immutable after initialization and the 9321cb0ef41Sopenharmony_ci // context itself is read through an atomic load. 9331cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), current); 9341cb0ef41Sopenharmony_ci} 9351cb0ef41Sopenharmony_ci 9361cb0ef41Sopenharmony_cibase::Optional<ObjectRef> ContextRef::get(int index) const { 9371cb0ef41Sopenharmony_ci CHECK_LE(0, index); 9381cb0ef41Sopenharmony_ci // Length is immutable after initialization. 9391cb0ef41Sopenharmony_ci if (index >= object()->length(kRelaxedLoad)) return {}; 9401cb0ef41Sopenharmony_ci return TryMakeRef(broker(), object()->get(index)); 9411cb0ef41Sopenharmony_ci} 9421cb0ef41Sopenharmony_ci 9431cb0ef41Sopenharmony_civoid JSHeapBroker::InitializeAndStartSerializing() { 9441cb0ef41Sopenharmony_ci TraceScope tracer(this, "JSHeapBroker::InitializeAndStartSerializing"); 9451cb0ef41Sopenharmony_ci 9461cb0ef41Sopenharmony_ci CHECK_EQ(mode_, kDisabled); 9471cb0ef41Sopenharmony_ci mode_ = kSerializing; 9481cb0ef41Sopenharmony_ci 9491cb0ef41Sopenharmony_ci // Throw away the dummy data that we created while disabled. 9501cb0ef41Sopenharmony_ci feedback_.clear(); 9511cb0ef41Sopenharmony_ci refs_->Clear(); 9521cb0ef41Sopenharmony_ci refs_ = 9531cb0ef41Sopenharmony_ci zone()->New<RefsMap>(kInitialRefsBucketCount, AddressMatcher(), zone()); 9541cb0ef41Sopenharmony_ci 9551cb0ef41Sopenharmony_ci CollectArrayAndObjectPrototypes(); 9561cb0ef41Sopenharmony_ci 9571cb0ef41Sopenharmony_ci SetTargetNativeContextRef(target_native_context().object()); 9581cb0ef41Sopenharmony_ci} 9591cb0ef41Sopenharmony_ci 9601cb0ef41Sopenharmony_cinamespace { 9611cb0ef41Sopenharmony_ci 9621cb0ef41Sopenharmony_ciconstexpr ObjectDataKind ObjectDataKindFor(RefSerializationKind kind) { 9631cb0ef41Sopenharmony_ci switch (kind) { 9641cb0ef41Sopenharmony_ci case RefSerializationKind::kBackgroundSerialized: 9651cb0ef41Sopenharmony_ci return kBackgroundSerializedHeapObject; 9661cb0ef41Sopenharmony_ci case RefSerializationKind::kNeverSerialized: 9671cb0ef41Sopenharmony_ci return kNeverSerializedHeapObject; 9681cb0ef41Sopenharmony_ci } 9691cb0ef41Sopenharmony_ci} 9701cb0ef41Sopenharmony_ci 9711cb0ef41Sopenharmony_ci} // namespace 9721cb0ef41Sopenharmony_ci 9731cb0ef41Sopenharmony_ciObjectData* JSHeapBroker::TryGetOrCreateData(Handle<Object> object, 9741cb0ef41Sopenharmony_ci GetOrCreateDataFlags flags) { 9751cb0ef41Sopenharmony_ci RefsMap::Entry* entry = refs_->Lookup(object.address()); 9761cb0ef41Sopenharmony_ci if (entry != nullptr) return entry->value; 9771cb0ef41Sopenharmony_ci 9781cb0ef41Sopenharmony_ci if (mode() == JSHeapBroker::kDisabled) { 9791cb0ef41Sopenharmony_ci entry = refs_->LookupOrInsert(object.address()); 9801cb0ef41Sopenharmony_ci ObjectData** storage = &entry->value; 9811cb0ef41Sopenharmony_ci if (*storage == nullptr) { 9821cb0ef41Sopenharmony_ci entry->value = zone()->New<ObjectData>( 9831cb0ef41Sopenharmony_ci this, storage, object, 9841cb0ef41Sopenharmony_ci object->IsSmi() ? kSmi : kUnserializedHeapObject); 9851cb0ef41Sopenharmony_ci } 9861cb0ef41Sopenharmony_ci return *storage; 9871cb0ef41Sopenharmony_ci } 9881cb0ef41Sopenharmony_ci 9891cb0ef41Sopenharmony_ci CHECK(mode() == JSHeapBroker::kSerializing || 9901cb0ef41Sopenharmony_ci mode() == JSHeapBroker::kSerialized); 9911cb0ef41Sopenharmony_ci 9921cb0ef41Sopenharmony_ci ObjectData* object_data; 9931cb0ef41Sopenharmony_ci if (object->IsSmi()) { 9941cb0ef41Sopenharmony_ci entry = refs_->LookupOrInsert(object.address()); 9951cb0ef41Sopenharmony_ci return zone()->New<ObjectData>(this, &entry->value, object, kSmi); 9961cb0ef41Sopenharmony_ci } 9971cb0ef41Sopenharmony_ci 9981cb0ef41Sopenharmony_ci DCHECK(!object->IsSmi()); 9991cb0ef41Sopenharmony_ci 10001cb0ef41Sopenharmony_ci const bool crash_on_error = (flags & kCrashOnError) != 0; 10011cb0ef41Sopenharmony_ci 10021cb0ef41Sopenharmony_ci if ((flags & kAssumeMemoryFence) == 0 && 10031cb0ef41Sopenharmony_ci ObjectMayBeUninitialized(HeapObject::cast(*object))) { 10041cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(this, "Object may be uninitialized " << *object); 10051cb0ef41Sopenharmony_ci CHECK_WITH_MSG(!crash_on_error, "Ref construction failed"); 10061cb0ef41Sopenharmony_ci return nullptr; 10071cb0ef41Sopenharmony_ci } 10081cb0ef41Sopenharmony_ci 10091cb0ef41Sopenharmony_ci if (IsReadOnlyHeapObjectForCompiler(isolate(), HeapObject::cast(*object))) { 10101cb0ef41Sopenharmony_ci entry = refs_->LookupOrInsert(object.address()); 10111cb0ef41Sopenharmony_ci return zone()->New<ObjectData>(this, &entry->value, object, 10121cb0ef41Sopenharmony_ci kUnserializedReadOnlyHeapObject); 10131cb0ef41Sopenharmony_ci } 10141cb0ef41Sopenharmony_ci 10151cb0ef41Sopenharmony_ci#define CREATE_DATA(Name) \ 10161cb0ef41Sopenharmony_ci if (object->Is##Name()) { \ 10171cb0ef41Sopenharmony_ci entry = refs_->LookupOrInsert(object.address()); \ 10181cb0ef41Sopenharmony_ci object_data = zone()->New<ref_traits<Name>::data_type>( \ 10191cb0ef41Sopenharmony_ci this, &entry->value, Handle<Name>::cast(object), \ 10201cb0ef41Sopenharmony_ci ObjectDataKindFor(ref_traits<Name>::ref_serialization_kind)); \ 10211cb0ef41Sopenharmony_ci /* NOLINTNEXTLINE(readability/braces) */ \ 10221cb0ef41Sopenharmony_ci } else 10231cb0ef41Sopenharmony_ci HEAP_BROKER_OBJECT_LIST(CREATE_DATA) 10241cb0ef41Sopenharmony_ci#undef CREATE_DATA 10251cb0ef41Sopenharmony_ci { 10261cb0ef41Sopenharmony_ci UNREACHABLE(); 10271cb0ef41Sopenharmony_ci } 10281cb0ef41Sopenharmony_ci // At this point the entry pointer is not guaranteed to be valid as 10291cb0ef41Sopenharmony_ci // the refs_ hash hable could be resized by one of the constructors above. 10301cb0ef41Sopenharmony_ci DCHECK_EQ(object_data, refs_->Lookup(object.address())->value); 10311cb0ef41Sopenharmony_ci return object_data; 10321cb0ef41Sopenharmony_ci} 10331cb0ef41Sopenharmony_ci 10341cb0ef41Sopenharmony_ci#define DEFINE_IS_AND_AS(Name) \ 10351cb0ef41Sopenharmony_ci bool ObjectRef::Is##Name() const { return data()->Is##Name(); } \ 10361cb0ef41Sopenharmony_ci Name##Ref ObjectRef::As##Name() const { \ 10371cb0ef41Sopenharmony_ci DCHECK(Is##Name()); \ 10381cb0ef41Sopenharmony_ci return Name##Ref(broker(), data()); \ 10391cb0ef41Sopenharmony_ci } 10401cb0ef41Sopenharmony_ciHEAP_BROKER_OBJECT_LIST(DEFINE_IS_AND_AS) 10411cb0ef41Sopenharmony_ci#undef DEFINE_IS_AND_AS 10421cb0ef41Sopenharmony_ci 10431cb0ef41Sopenharmony_cibool ObjectRef::IsSmi() const { return data()->is_smi(); } 10441cb0ef41Sopenharmony_ci 10451cb0ef41Sopenharmony_ciint ObjectRef::AsSmi() const { 10461cb0ef41Sopenharmony_ci DCHECK(IsSmi()); 10471cb0ef41Sopenharmony_ci // Handle-dereference is always allowed for Handle<Smi>. 10481cb0ef41Sopenharmony_ci return Handle<Smi>::cast(object())->value(); 10491cb0ef41Sopenharmony_ci} 10501cb0ef41Sopenharmony_ci 10511cb0ef41Sopenharmony_ci#define DEF_TESTER(Type, ...) \ 10521cb0ef41Sopenharmony_ci bool MapRef::Is##Type##Map() const { \ 10531cb0ef41Sopenharmony_ci return InstanceTypeChecker::Is##Type(instance_type()); \ 10541cb0ef41Sopenharmony_ci } 10551cb0ef41Sopenharmony_ciINSTANCE_TYPE_CHECKERS(DEF_TESTER) 10561cb0ef41Sopenharmony_ci#undef DEF_TESTER 10571cb0ef41Sopenharmony_ci 10581cb0ef41Sopenharmony_cibool MapRef::CanInlineElementAccess() const { 10591cb0ef41Sopenharmony_ci if (!IsJSObjectMap()) return false; 10601cb0ef41Sopenharmony_ci if (is_access_check_needed()) return false; 10611cb0ef41Sopenharmony_ci if (has_indexed_interceptor()) return false; 10621cb0ef41Sopenharmony_ci ElementsKind kind = elements_kind(); 10631cb0ef41Sopenharmony_ci if (IsFastElementsKind(kind)) return true; 10641cb0ef41Sopenharmony_ci if (IsTypedArrayElementsKind(kind) && kind != BIGUINT64_ELEMENTS && 10651cb0ef41Sopenharmony_ci kind != BIGINT64_ELEMENTS) { 10661cb0ef41Sopenharmony_ci return true; 10671cb0ef41Sopenharmony_ci } 10681cb0ef41Sopenharmony_ci return false; 10691cb0ef41Sopenharmony_ci} 10701cb0ef41Sopenharmony_ci 10711cb0ef41Sopenharmony_cibase::Optional<MapRef> MapRef::AsElementsKind(ElementsKind kind) const { 10721cb0ef41Sopenharmony_ci const ElementsKind current_kind = elements_kind(); 10731cb0ef41Sopenharmony_ci if (kind == current_kind) return *this; 10741cb0ef41Sopenharmony_ci 10751cb0ef41Sopenharmony_ci base::Optional<Map> maybe_result = Map::TryAsElementsKind( 10761cb0ef41Sopenharmony_ci broker()->isolate(), object(), kind, ConcurrencyMode::kConcurrent); 10771cb0ef41Sopenharmony_ci 10781cb0ef41Sopenharmony_ci#ifdef DEBUG 10791cb0ef41Sopenharmony_ci // If starting from an initial JSArray map, TryAsElementsKind must succeed 10801cb0ef41Sopenharmony_ci // and return the expected transitioned JSArray map. 10811cb0ef41Sopenharmony_ci NativeContextRef native_context = broker()->target_native_context(); 10821cb0ef41Sopenharmony_ci if (equals(native_context.GetInitialJSArrayMap(current_kind))) { 10831cb0ef41Sopenharmony_ci CHECK_EQ(Map::TryAsElementsKind(broker()->isolate(), object(), kind, 10841cb0ef41Sopenharmony_ci ConcurrencyMode::kConcurrent) 10851cb0ef41Sopenharmony_ci .value(), 10861cb0ef41Sopenharmony_ci *native_context.GetInitialJSArrayMap(kind).object()); 10871cb0ef41Sopenharmony_ci } 10881cb0ef41Sopenharmony_ci#endif // DEBUG 10891cb0ef41Sopenharmony_ci 10901cb0ef41Sopenharmony_ci if (!maybe_result.has_value()) { 10911cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker(), "MapRef::AsElementsKind " << *this); 10921cb0ef41Sopenharmony_ci return {}; 10931cb0ef41Sopenharmony_ci } 10941cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), maybe_result.value()); 10951cb0ef41Sopenharmony_ci} 10961cb0ef41Sopenharmony_ci 10971cb0ef41Sopenharmony_cibool MapRef::HasOnlyStablePrototypesWithFastElements( 10981cb0ef41Sopenharmony_ci ZoneVector<MapRef>* prototype_maps) { 10991cb0ef41Sopenharmony_ci DCHECK_NOT_NULL(prototype_maps); 11001cb0ef41Sopenharmony_ci MapRef prototype_map = prototype().map(); 11011cb0ef41Sopenharmony_ci while (prototype_map.oddball_type() != OddballType::kNull) { 11021cb0ef41Sopenharmony_ci if (!prototype_map.IsJSObjectMap() || !prototype_map.is_stable() || 11031cb0ef41Sopenharmony_ci !IsFastElementsKind(prototype_map.elements_kind())) { 11041cb0ef41Sopenharmony_ci return false; 11051cb0ef41Sopenharmony_ci } 11061cb0ef41Sopenharmony_ci prototype_maps->push_back(prototype_map); 11071cb0ef41Sopenharmony_ci prototype_map = prototype_map.prototype().map(); 11081cb0ef41Sopenharmony_ci } 11091cb0ef41Sopenharmony_ci return true; 11101cb0ef41Sopenharmony_ci} 11111cb0ef41Sopenharmony_ci 11121cb0ef41Sopenharmony_cibool MapRef::supports_fast_array_iteration() const { 11131cb0ef41Sopenharmony_ci return SupportsFastArrayIteration(broker(), object()); 11141cb0ef41Sopenharmony_ci} 11151cb0ef41Sopenharmony_ci 11161cb0ef41Sopenharmony_cibool MapRef::supports_fast_array_resize() const { 11171cb0ef41Sopenharmony_ci return SupportsFastArrayResize(broker(), object()); 11181cb0ef41Sopenharmony_ci} 11191cb0ef41Sopenharmony_ci 11201cb0ef41Sopenharmony_cinamespace { 11211cb0ef41Sopenharmony_ci 11221cb0ef41Sopenharmony_civoid RecordConsistentJSFunctionViewDependencyIfNeeded( 11231cb0ef41Sopenharmony_ci const JSHeapBroker* broker, const JSFunctionRef& ref, JSFunctionData* data, 11241cb0ef41Sopenharmony_ci JSFunctionData::UsedField used_field) { 11251cb0ef41Sopenharmony_ci if (!data->has_any_used_field()) { 11261cb0ef41Sopenharmony_ci // Deduplicate dependencies. 11271cb0ef41Sopenharmony_ci broker->dependencies()->DependOnConsistentJSFunctionView(ref); 11281cb0ef41Sopenharmony_ci } 11291cb0ef41Sopenharmony_ci data->set_used_field(used_field); 11301cb0ef41Sopenharmony_ci} 11311cb0ef41Sopenharmony_ci 11321cb0ef41Sopenharmony_ci} // namespace 11331cb0ef41Sopenharmony_ci 11341cb0ef41Sopenharmony_cibase::Optional<FeedbackVectorRef> JSFunctionRef::feedback_vector( 11351cb0ef41Sopenharmony_ci CompilationDependencies* dependencies) const { 11361cb0ef41Sopenharmony_ci return raw_feedback_cell(dependencies).feedback_vector(); 11371cb0ef41Sopenharmony_ci} 11381cb0ef41Sopenharmony_ci 11391cb0ef41Sopenharmony_ciint JSFunctionRef::InitialMapInstanceSizeWithMinSlack( 11401cb0ef41Sopenharmony_ci CompilationDependencies* dependencies) const { 11411cb0ef41Sopenharmony_ci if (data_->should_access_heap()) { 11421cb0ef41Sopenharmony_ci return object()->ComputeInstanceSizeWithMinSlack(broker()->isolate()); 11431cb0ef41Sopenharmony_ci } 11441cb0ef41Sopenharmony_ci RecordConsistentJSFunctionViewDependencyIfNeeded( 11451cb0ef41Sopenharmony_ci broker(), *this, data()->AsJSFunction(), 11461cb0ef41Sopenharmony_ci JSFunctionData::kInitialMapInstanceSizeWithMinSlack); 11471cb0ef41Sopenharmony_ci return data()->AsJSFunction()->initial_map_instance_size_with_min_slack(); 11481cb0ef41Sopenharmony_ci} 11491cb0ef41Sopenharmony_ci 11501cb0ef41Sopenharmony_ciOddballType MapRef::oddball_type() const { 11511cb0ef41Sopenharmony_ci if (instance_type() != ODDBALL_TYPE) { 11521cb0ef41Sopenharmony_ci return OddballType::kNone; 11531cb0ef41Sopenharmony_ci } 11541cb0ef41Sopenharmony_ci Factory* f = broker()->isolate()->factory(); 11551cb0ef41Sopenharmony_ci if (equals(MakeRef(broker(), f->undefined_map()))) { 11561cb0ef41Sopenharmony_ci return OddballType::kUndefined; 11571cb0ef41Sopenharmony_ci } 11581cb0ef41Sopenharmony_ci if (equals(MakeRef(broker(), f->null_map()))) { 11591cb0ef41Sopenharmony_ci return OddballType::kNull; 11601cb0ef41Sopenharmony_ci } 11611cb0ef41Sopenharmony_ci if (equals(MakeRef(broker(), f->boolean_map()))) { 11621cb0ef41Sopenharmony_ci return OddballType::kBoolean; 11631cb0ef41Sopenharmony_ci } 11641cb0ef41Sopenharmony_ci if (equals(MakeRef(broker(), f->the_hole_map()))) { 11651cb0ef41Sopenharmony_ci return OddballType::kHole; 11661cb0ef41Sopenharmony_ci } 11671cb0ef41Sopenharmony_ci if (equals(MakeRef(broker(), f->uninitialized_map()))) { 11681cb0ef41Sopenharmony_ci return OddballType::kUninitialized; 11691cb0ef41Sopenharmony_ci } 11701cb0ef41Sopenharmony_ci DCHECK(equals(MakeRef(broker(), f->termination_exception_map())) || 11711cb0ef41Sopenharmony_ci equals(MakeRef(broker(), f->arguments_marker_map())) || 11721cb0ef41Sopenharmony_ci equals(MakeRef(broker(), f->optimized_out_map())) || 11731cb0ef41Sopenharmony_ci equals(MakeRef(broker(), f->stale_register_map()))); 11741cb0ef41Sopenharmony_ci return OddballType::kOther; 11751cb0ef41Sopenharmony_ci} 11761cb0ef41Sopenharmony_ci 11771cb0ef41Sopenharmony_ciFeedbackCellRef FeedbackVectorRef::GetClosureFeedbackCell(int index) const { 11781cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), 11791cb0ef41Sopenharmony_ci object()->closure_feedback_cell(index)); 11801cb0ef41Sopenharmony_ci} 11811cb0ef41Sopenharmony_ci 11821cb0ef41Sopenharmony_cibase::Optional<ObjectRef> JSObjectRef::raw_properties_or_hash() const { 11831cb0ef41Sopenharmony_ci return TryMakeRef(broker(), object()->raw_properties_or_hash()); 11841cb0ef41Sopenharmony_ci} 11851cb0ef41Sopenharmony_ci 11861cb0ef41Sopenharmony_cibase::Optional<ObjectRef> JSObjectRef::RawInobjectPropertyAt( 11871cb0ef41Sopenharmony_ci FieldIndex index) const { 11881cb0ef41Sopenharmony_ci CHECK(index.is_inobject()); 11891cb0ef41Sopenharmony_ci Handle<Object> value; 11901cb0ef41Sopenharmony_ci { 11911cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 11921cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = broker()->cage_base(); 11931cb0ef41Sopenharmony_ci Map current_map = object()->map(cage_base, kAcquireLoad); 11941cb0ef41Sopenharmony_ci 11951cb0ef41Sopenharmony_ci // If the map changed in some prior GC epoch, our {index} could be 11961cb0ef41Sopenharmony_ci // outside the valid bounds of the cached map. 11971cb0ef41Sopenharmony_ci if (*map().object() != current_map) { 11981cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker(), "Map change detected in " << *this); 11991cb0ef41Sopenharmony_ci return {}; 12001cb0ef41Sopenharmony_ci } 12011cb0ef41Sopenharmony_ci 12021cb0ef41Sopenharmony_ci base::Optional<Object> maybe_value = 12031cb0ef41Sopenharmony_ci object()->RawInobjectPropertyAt(cage_base, current_map, index); 12041cb0ef41Sopenharmony_ci if (!maybe_value.has_value()) { 12051cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker(), 12061cb0ef41Sopenharmony_ci "Unable to safely read property in " << *this); 12071cb0ef41Sopenharmony_ci return {}; 12081cb0ef41Sopenharmony_ci } 12091cb0ef41Sopenharmony_ci value = broker()->CanonicalPersistentHandle(maybe_value.value()); 12101cb0ef41Sopenharmony_ci } 12111cb0ef41Sopenharmony_ci return TryMakeRef(broker(), value); 12121cb0ef41Sopenharmony_ci} 12131cb0ef41Sopenharmony_ci 12141cb0ef41Sopenharmony_cibool JSObjectRef::IsElementsTenured(const FixedArrayBaseRef& elements) { 12151cb0ef41Sopenharmony_ci return !ObjectInYoungGeneration(*elements.object()); 12161cb0ef41Sopenharmony_ci} 12171cb0ef41Sopenharmony_ci 12181cb0ef41Sopenharmony_ciFieldIndex MapRef::GetFieldIndexFor(InternalIndex descriptor_index) const { 12191cb0ef41Sopenharmony_ci CHECK_LT(descriptor_index.as_int(), NumberOfOwnDescriptors()); 12201cb0ef41Sopenharmony_ci FieldIndex result = FieldIndex::ForDescriptor(*object(), descriptor_index); 12211cb0ef41Sopenharmony_ci DCHECK(result.is_inobject()); 12221cb0ef41Sopenharmony_ci return result; 12231cb0ef41Sopenharmony_ci} 12241cb0ef41Sopenharmony_ci 12251cb0ef41Sopenharmony_ciint MapRef::GetInObjectPropertyOffset(int i) const { 12261cb0ef41Sopenharmony_ci return object()->GetInObjectPropertyOffset(i); 12271cb0ef41Sopenharmony_ci} 12281cb0ef41Sopenharmony_ci 12291cb0ef41Sopenharmony_ciPropertyDetails MapRef::GetPropertyDetails( 12301cb0ef41Sopenharmony_ci InternalIndex descriptor_index) const { 12311cb0ef41Sopenharmony_ci CHECK_LT(descriptor_index.as_int(), NumberOfOwnDescriptors()); 12321cb0ef41Sopenharmony_ci return instance_descriptors().GetPropertyDetails(descriptor_index); 12331cb0ef41Sopenharmony_ci} 12341cb0ef41Sopenharmony_ci 12351cb0ef41Sopenharmony_ciNameRef MapRef::GetPropertyKey(InternalIndex descriptor_index) const { 12361cb0ef41Sopenharmony_ci CHECK_LT(descriptor_index.as_int(), NumberOfOwnDescriptors()); 12371cb0ef41Sopenharmony_ci return instance_descriptors().GetPropertyKey(descriptor_index); 12381cb0ef41Sopenharmony_ci} 12391cb0ef41Sopenharmony_ci 12401cb0ef41Sopenharmony_cibool MapRef::IsFixedCowArrayMap() const { 12411cb0ef41Sopenharmony_ci Handle<Map> fixed_cow_array_map = 12421cb0ef41Sopenharmony_ci ReadOnlyRoots(broker()->isolate()).fixed_cow_array_map_handle(); 12431cb0ef41Sopenharmony_ci return equals(MakeRef(broker(), fixed_cow_array_map)); 12441cb0ef41Sopenharmony_ci} 12451cb0ef41Sopenharmony_ci 12461cb0ef41Sopenharmony_cibool MapRef::IsPrimitiveMap() const { 12471cb0ef41Sopenharmony_ci return instance_type() <= LAST_PRIMITIVE_HEAP_OBJECT_TYPE; 12481cb0ef41Sopenharmony_ci} 12491cb0ef41Sopenharmony_ci 12501cb0ef41Sopenharmony_ciMapRef MapRef::FindFieldOwner(InternalIndex descriptor_index) const { 12511cb0ef41Sopenharmony_ci CHECK_LT(descriptor_index.as_int(), NumberOfOwnDescriptors()); 12521cb0ef41Sopenharmony_ci // TODO(solanes, v8:7790): Consider caching the result of the field owner on 12531cb0ef41Sopenharmony_ci // the descriptor array. It would be useful for same map as well as any 12541cb0ef41Sopenharmony_ci // other map sharing that descriptor array. 12551cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence( 12561cb0ef41Sopenharmony_ci broker(), 12571cb0ef41Sopenharmony_ci object()->FindFieldOwner(broker()->isolate(), descriptor_index)); 12581cb0ef41Sopenharmony_ci} 12591cb0ef41Sopenharmony_ci 12601cb0ef41Sopenharmony_cibase::Optional<ObjectRef> StringRef::GetCharAsStringOrUndefined( 12611cb0ef41Sopenharmony_ci uint32_t index) const { 12621cb0ef41Sopenharmony_ci String maybe_char; 12631cb0ef41Sopenharmony_ci auto result = ConcurrentLookupIterator::TryGetOwnChar( 12641cb0ef41Sopenharmony_ci &maybe_char, broker()->isolate(), broker()->local_isolate(), *object(), 12651cb0ef41Sopenharmony_ci index); 12661cb0ef41Sopenharmony_ci 12671cb0ef41Sopenharmony_ci if (result == ConcurrentLookupIterator::kGaveUp) { 12681cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker(), "StringRef::GetCharAsStringOrUndefined on " 12691cb0ef41Sopenharmony_ci << *this << " at index " << index); 12701cb0ef41Sopenharmony_ci return {}; 12711cb0ef41Sopenharmony_ci } 12721cb0ef41Sopenharmony_ci 12731cb0ef41Sopenharmony_ci DCHECK_EQ(result, ConcurrentLookupIterator::kPresent); 12741cb0ef41Sopenharmony_ci return TryMakeRef(broker(), maybe_char); 12751cb0ef41Sopenharmony_ci} 12761cb0ef41Sopenharmony_ci 12771cb0ef41Sopenharmony_cibool StringRef::SupportedStringKind() const { 12781cb0ef41Sopenharmony_ci return IsInternalizedString() || object()->IsThinString(); 12791cb0ef41Sopenharmony_ci} 12801cb0ef41Sopenharmony_ci 12811cb0ef41Sopenharmony_cibase::Optional<Handle<String>> StringRef::ObjectIfContentAccessible() { 12821cb0ef41Sopenharmony_ci if (data_->kind() == kNeverSerializedHeapObject && !SupportedStringKind()) { 12831cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING( 12841cb0ef41Sopenharmony_ci broker(), 12851cb0ef41Sopenharmony_ci "content for kNeverSerialized unsupported string kind " << *this); 12861cb0ef41Sopenharmony_ci return base::nullopt; 12871cb0ef41Sopenharmony_ci } else { 12881cb0ef41Sopenharmony_ci return object(); 12891cb0ef41Sopenharmony_ci } 12901cb0ef41Sopenharmony_ci} 12911cb0ef41Sopenharmony_ci 12921cb0ef41Sopenharmony_cibase::Optional<int> StringRef::length() const { 12931cb0ef41Sopenharmony_ci if (data_->kind() == kNeverSerializedHeapObject && !SupportedStringKind()) { 12941cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING( 12951cb0ef41Sopenharmony_ci broker(), 12961cb0ef41Sopenharmony_ci "length for kNeverSerialized unsupported string kind " << *this); 12971cb0ef41Sopenharmony_ci return base::nullopt; 12981cb0ef41Sopenharmony_ci } else { 12991cb0ef41Sopenharmony_ci return object()->length(kAcquireLoad); 13001cb0ef41Sopenharmony_ci } 13011cb0ef41Sopenharmony_ci} 13021cb0ef41Sopenharmony_ci 13031cb0ef41Sopenharmony_cibase::Optional<uint16_t> StringRef::GetFirstChar() const { return GetChar(0); } 13041cb0ef41Sopenharmony_ci 13051cb0ef41Sopenharmony_cibase::Optional<uint16_t> StringRef::GetChar(int index) const { 13061cb0ef41Sopenharmony_ci if (data_->kind() == kNeverSerializedHeapObject && !SupportedStringKind()) { 13071cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING( 13081cb0ef41Sopenharmony_ci broker(), 13091cb0ef41Sopenharmony_ci "get char for kNeverSerialized unsupported string kind " << *this); 13101cb0ef41Sopenharmony_ci return base::nullopt; 13111cb0ef41Sopenharmony_ci } 13121cb0ef41Sopenharmony_ci 13131cb0ef41Sopenharmony_ci if (!broker()->IsMainThread()) { 13141cb0ef41Sopenharmony_ci return object()->Get(index, broker()->local_isolate()); 13151cb0ef41Sopenharmony_ci } else { 13161cb0ef41Sopenharmony_ci // TODO(solanes, v8:7790): Remove this case once the inlining phase is 13171cb0ef41Sopenharmony_ci // done concurrently all the time. 13181cb0ef41Sopenharmony_ci return object()->Get(index); 13191cb0ef41Sopenharmony_ci } 13201cb0ef41Sopenharmony_ci} 13211cb0ef41Sopenharmony_ci 13221cb0ef41Sopenharmony_cibase::Optional<double> StringRef::ToNumber() { 13231cb0ef41Sopenharmony_ci if (data_->kind() == kNeverSerializedHeapObject && !SupportedStringKind()) { 13241cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING( 13251cb0ef41Sopenharmony_ci broker(), 13261cb0ef41Sopenharmony_ci "number for kNeverSerialized unsupported string kind " << *this); 13271cb0ef41Sopenharmony_ci return base::nullopt; 13281cb0ef41Sopenharmony_ci } 13291cb0ef41Sopenharmony_ci 13301cb0ef41Sopenharmony_ci return TryStringToDouble(broker()->local_isolate(), object()); 13311cb0ef41Sopenharmony_ci} 13321cb0ef41Sopenharmony_ci 13331cb0ef41Sopenharmony_ciint ArrayBoilerplateDescriptionRef::constants_elements_length() const { 13341cb0ef41Sopenharmony_ci return object()->constant_elements().length(); 13351cb0ef41Sopenharmony_ci} 13361cb0ef41Sopenharmony_ci 13371cb0ef41Sopenharmony_cibase::Optional<ObjectRef> FixedArrayRef::TryGet(int i) const { 13381cb0ef41Sopenharmony_ci Handle<Object> value; 13391cb0ef41Sopenharmony_ci { 13401cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 13411cb0ef41Sopenharmony_ci CHECK_GE(i, 0); 13421cb0ef41Sopenharmony_ci value = broker()->CanonicalPersistentHandle(object()->get(i, kAcquireLoad)); 13431cb0ef41Sopenharmony_ci if (i >= object()->length(kAcquireLoad)) { 13441cb0ef41Sopenharmony_ci // Right-trimming happened. 13451cb0ef41Sopenharmony_ci CHECK_LT(i, length()); 13461cb0ef41Sopenharmony_ci return {}; 13471cb0ef41Sopenharmony_ci } 13481cb0ef41Sopenharmony_ci } 13491cb0ef41Sopenharmony_ci return TryMakeRef(broker(), value); 13501cb0ef41Sopenharmony_ci} 13511cb0ef41Sopenharmony_ci 13521cb0ef41Sopenharmony_ciFloat64 FixedDoubleArrayRef::GetFromImmutableFixedDoubleArray(int i) const { 13531cb0ef41Sopenharmony_ci STATIC_ASSERT(ref_traits<FixedDoubleArray>::ref_serialization_kind == 13541cb0ef41Sopenharmony_ci RefSerializationKind::kNeverSerialized); 13551cb0ef41Sopenharmony_ci CHECK(data_->should_access_heap()); 13561cb0ef41Sopenharmony_ci return Float64::FromBits(object()->get_representation(i)); 13571cb0ef41Sopenharmony_ci} 13581cb0ef41Sopenharmony_ci 13591cb0ef41Sopenharmony_ciHandle<ByteArray> BytecodeArrayRef::SourcePositionTable() const { 13601cb0ef41Sopenharmony_ci return broker()->CanonicalPersistentHandle(object()->SourcePositionTable()); 13611cb0ef41Sopenharmony_ci} 13621cb0ef41Sopenharmony_ci 13631cb0ef41Sopenharmony_ciAddress BytecodeArrayRef::handler_table_address() const { 13641cb0ef41Sopenharmony_ci return reinterpret_cast<Address>( 13651cb0ef41Sopenharmony_ci object()->handler_table().GetDataStartAddress()); 13661cb0ef41Sopenharmony_ci} 13671cb0ef41Sopenharmony_ci 13681cb0ef41Sopenharmony_ciint BytecodeArrayRef::handler_table_size() const { 13691cb0ef41Sopenharmony_ci return object()->handler_table().length(); 13701cb0ef41Sopenharmony_ci} 13711cb0ef41Sopenharmony_ci 13721cb0ef41Sopenharmony_ci#define IF_ACCESS_FROM_HEAP_C(name) \ 13731cb0ef41Sopenharmony_ci if (data_->should_access_heap()) { \ 13741cb0ef41Sopenharmony_ci return object()->name(); \ 13751cb0ef41Sopenharmony_ci } 13761cb0ef41Sopenharmony_ci 13771cb0ef41Sopenharmony_ci#define IF_ACCESS_FROM_HEAP(result, name) \ 13781cb0ef41Sopenharmony_ci if (data_->should_access_heap()) { \ 13791cb0ef41Sopenharmony_ci return MakeRef(broker(), result::cast(object()->name())); \ 13801cb0ef41Sopenharmony_ci } 13811cb0ef41Sopenharmony_ci 13821cb0ef41Sopenharmony_ci// Macros for definining a const getter that, depending on the data kind, 13831cb0ef41Sopenharmony_ci// either looks into the heap or into the serialized data. 13841cb0ef41Sopenharmony_ci#define BIMODAL_ACCESSOR(holder, result, name) \ 13851cb0ef41Sopenharmony_ci result##Ref holder##Ref::name() const { \ 13861cb0ef41Sopenharmony_ci IF_ACCESS_FROM_HEAP(result, name); \ 13871cb0ef41Sopenharmony_ci return result##Ref(broker(), ObjectRef::data()->As##holder()->name()); \ 13881cb0ef41Sopenharmony_ci } 13891cb0ef41Sopenharmony_ci 13901cb0ef41Sopenharmony_ci// Like above except that the result type is not an XYZRef. 13911cb0ef41Sopenharmony_ci#define BIMODAL_ACCESSOR_C(holder, result, name) \ 13921cb0ef41Sopenharmony_ci result holder##Ref::name() const { \ 13931cb0ef41Sopenharmony_ci IF_ACCESS_FROM_HEAP_C(name); \ 13941cb0ef41Sopenharmony_ci return ObjectRef::data()->As##holder()->name(); \ 13951cb0ef41Sopenharmony_ci } 13961cb0ef41Sopenharmony_ci 13971cb0ef41Sopenharmony_ci// Like above but for BitFields. 13981cb0ef41Sopenharmony_ci#define BIMODAL_ACCESSOR_B(holder, field, name, BitField) \ 13991cb0ef41Sopenharmony_ci typename BitField::FieldType holder##Ref::name() const { \ 14001cb0ef41Sopenharmony_ci IF_ACCESS_FROM_HEAP_C(name); \ 14011cb0ef41Sopenharmony_ci return BitField::decode(ObjectRef::data()->As##holder()->field()); \ 14021cb0ef41Sopenharmony_ci } 14031cb0ef41Sopenharmony_ci 14041cb0ef41Sopenharmony_ci#define HEAP_ACCESSOR_C(holder, result, name) \ 14051cb0ef41Sopenharmony_ci result holder##Ref::name() const { return object()->name(); } 14061cb0ef41Sopenharmony_ci 14071cb0ef41Sopenharmony_ci#define HEAP_ACCESSOR_B(holder, field, name, BitField) \ 14081cb0ef41Sopenharmony_ci typename BitField::FieldType holder##Ref::name() const { \ 14091cb0ef41Sopenharmony_ci return object()->name(); \ 14101cb0ef41Sopenharmony_ci } 14111cb0ef41Sopenharmony_ci 14121cb0ef41Sopenharmony_ciObjectRef AllocationSiteRef::nested_site() const { 14131cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), object()->nested_site()); 14141cb0ef41Sopenharmony_ci} 14151cb0ef41Sopenharmony_ci 14161cb0ef41Sopenharmony_ciHEAP_ACCESSOR_C(AllocationSite, bool, CanInlineCall) 14171cb0ef41Sopenharmony_ciHEAP_ACCESSOR_C(AllocationSite, bool, PointsToLiteral) 14181cb0ef41Sopenharmony_ciHEAP_ACCESSOR_C(AllocationSite, ElementsKind, GetElementsKind) 14191cb0ef41Sopenharmony_ciHEAP_ACCESSOR_C(AllocationSite, AllocationType, GetAllocationType) 14201cb0ef41Sopenharmony_ci 14211cb0ef41Sopenharmony_ciBIMODAL_ACCESSOR_C(BigInt, uint64_t, AsUint64) 14221cb0ef41Sopenharmony_ci 14231cb0ef41Sopenharmony_ciint BytecodeArrayRef::register_count() const { 14241cb0ef41Sopenharmony_ci return object()->register_count(); 14251cb0ef41Sopenharmony_ci} 14261cb0ef41Sopenharmony_ciint BytecodeArrayRef::parameter_count() const { 14271cb0ef41Sopenharmony_ci return object()->parameter_count(); 14281cb0ef41Sopenharmony_ci} 14291cb0ef41Sopenharmony_ciinterpreter::Register 14301cb0ef41Sopenharmony_ciBytecodeArrayRef::incoming_new_target_or_generator_register() const { 14311cb0ef41Sopenharmony_ci return object()->incoming_new_target_or_generator_register(); 14321cb0ef41Sopenharmony_ci} 14331cb0ef41Sopenharmony_ci 14341cb0ef41Sopenharmony_ciBIMODAL_ACCESSOR(HeapObject, Map, map) 14351cb0ef41Sopenharmony_ci 14361cb0ef41Sopenharmony_ciHEAP_ACCESSOR_C(HeapNumber, double, value) 14371cb0ef41Sopenharmony_ci 14381cb0ef41Sopenharmony_ciuint64_t HeapNumberRef::value_as_bits() const { 14391cb0ef41Sopenharmony_ci return object()->value_as_bits(kRelaxedLoad); 14401cb0ef41Sopenharmony_ci} 14411cb0ef41Sopenharmony_ci 14421cb0ef41Sopenharmony_ciJSReceiverRef JSBoundFunctionRef::bound_target_function() const { 14431cb0ef41Sopenharmony_ci // Immutable after initialization. 14441cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), object()->bound_target_function()); 14451cb0ef41Sopenharmony_ci} 14461cb0ef41Sopenharmony_ci 14471cb0ef41Sopenharmony_ciObjectRef JSBoundFunctionRef::bound_this() const { 14481cb0ef41Sopenharmony_ci // Immutable after initialization. 14491cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), object()->bound_this()); 14501cb0ef41Sopenharmony_ci} 14511cb0ef41Sopenharmony_ci 14521cb0ef41Sopenharmony_ciFixedArrayRef JSBoundFunctionRef::bound_arguments() const { 14531cb0ef41Sopenharmony_ci // Immutable after initialization. 14541cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), object()->bound_arguments()); 14551cb0ef41Sopenharmony_ci} 14561cb0ef41Sopenharmony_ci 14571cb0ef41Sopenharmony_ci// Immutable after initialization. 14581cb0ef41Sopenharmony_ciHEAP_ACCESSOR_C(JSDataView, size_t, byte_length) 14591cb0ef41Sopenharmony_ci 14601cb0ef41Sopenharmony_ciHEAP_ACCESSOR_B(Map, bit_field2, elements_kind, Map::Bits2::ElementsKindBits) 14611cb0ef41Sopenharmony_ciHEAP_ACCESSOR_B(Map, bit_field3, is_dictionary_map, 14621cb0ef41Sopenharmony_ci Map::Bits3::IsDictionaryMapBit) 14631cb0ef41Sopenharmony_ciHEAP_ACCESSOR_B(Map, bit_field3, is_deprecated, Map::Bits3::IsDeprecatedBit) 14641cb0ef41Sopenharmony_ciHEAP_ACCESSOR_B(Map, bit_field3, NumberOfOwnDescriptors, 14651cb0ef41Sopenharmony_ci Map::Bits3::NumberOfOwnDescriptorsBits) 14661cb0ef41Sopenharmony_ciHEAP_ACCESSOR_B(Map, bit_field3, is_migration_target, 14671cb0ef41Sopenharmony_ci Map::Bits3::IsMigrationTargetBit) 14681cb0ef41Sopenharmony_ciHEAP_ACCESSOR_B(Map, bit_field, has_prototype_slot, 14691cb0ef41Sopenharmony_ci Map::Bits1::HasPrototypeSlotBit) 14701cb0ef41Sopenharmony_ciHEAP_ACCESSOR_B(Map, bit_field, is_access_check_needed, 14711cb0ef41Sopenharmony_ci Map::Bits1::IsAccessCheckNeededBit) 14721cb0ef41Sopenharmony_ciHEAP_ACCESSOR_B(Map, bit_field, is_callable, Map::Bits1::IsCallableBit) 14731cb0ef41Sopenharmony_ciHEAP_ACCESSOR_B(Map, bit_field, has_indexed_interceptor, 14741cb0ef41Sopenharmony_ci Map::Bits1::HasIndexedInterceptorBit) 14751cb0ef41Sopenharmony_ciHEAP_ACCESSOR_B(Map, bit_field, is_constructor, Map::Bits1::IsConstructorBit) 14761cb0ef41Sopenharmony_ciHEAP_ACCESSOR_B(Map, bit_field, is_undetectable, Map::Bits1::IsUndetectableBit) 14771cb0ef41Sopenharmony_ciBIMODAL_ACCESSOR_C(Map, int, instance_size) 14781cb0ef41Sopenharmony_ciHEAP_ACCESSOR_C(Map, int, NextFreePropertyIndex) 14791cb0ef41Sopenharmony_ciBIMODAL_ACCESSOR_C(Map, int, UnusedPropertyFields) 14801cb0ef41Sopenharmony_ciHEAP_ACCESSOR_C(Map, InstanceType, instance_type) 14811cb0ef41Sopenharmony_ciBIMODAL_ACCESSOR_C(Map, bool, is_abandoned_prototype_map) 14821cb0ef41Sopenharmony_ci 14831cb0ef41Sopenharmony_ciint ObjectBoilerplateDescriptionRef::size() const { return object()->size(); } 14841cb0ef41Sopenharmony_ci 14851cb0ef41Sopenharmony_ciBIMODAL_ACCESSOR(PropertyCell, Object, value) 14861cb0ef41Sopenharmony_ciBIMODAL_ACCESSOR_C(PropertyCell, PropertyDetails, property_details) 14871cb0ef41Sopenharmony_ci 14881cb0ef41Sopenharmony_ciFixedArrayRef RegExpBoilerplateDescriptionRef::data() const { 14891cb0ef41Sopenharmony_ci // Immutable after initialization. 14901cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), object()->data()); 14911cb0ef41Sopenharmony_ci} 14921cb0ef41Sopenharmony_ci 14931cb0ef41Sopenharmony_ciStringRef RegExpBoilerplateDescriptionRef::source() const { 14941cb0ef41Sopenharmony_ci // Immutable after initialization. 14951cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), object()->source()); 14961cb0ef41Sopenharmony_ci} 14971cb0ef41Sopenharmony_ci 14981cb0ef41Sopenharmony_ciint RegExpBoilerplateDescriptionRef::flags() const { return object()->flags(); } 14991cb0ef41Sopenharmony_ci 15001cb0ef41Sopenharmony_cibase::Optional<CallHandlerInfoRef> FunctionTemplateInfoRef::call_code() const { 15011cb0ef41Sopenharmony_ci HeapObject call_code = object()->call_code(kAcquireLoad); 15021cb0ef41Sopenharmony_ci if (call_code.IsUndefined()) return base::nullopt; 15031cb0ef41Sopenharmony_ci return TryMakeRef(broker(), CallHandlerInfo::cast(call_code)); 15041cb0ef41Sopenharmony_ci} 15051cb0ef41Sopenharmony_ci 15061cb0ef41Sopenharmony_cibool FunctionTemplateInfoRef::is_signature_undefined() const { 15071cb0ef41Sopenharmony_ci return object()->signature().IsUndefined(broker()->isolate()); 15081cb0ef41Sopenharmony_ci} 15091cb0ef41Sopenharmony_ci 15101cb0ef41Sopenharmony_ciHEAP_ACCESSOR_C(FunctionTemplateInfo, bool, accept_any_receiver) 15111cb0ef41Sopenharmony_ci 15121cb0ef41Sopenharmony_ciHolderLookupResult FunctionTemplateInfoRef::LookupHolderOfExpectedType( 15131cb0ef41Sopenharmony_ci MapRef receiver_map) { 15141cb0ef41Sopenharmony_ci const HolderLookupResult not_found; 15151cb0ef41Sopenharmony_ci if (!receiver_map.IsJSObjectMap() || (receiver_map.is_access_check_needed() && 15161cb0ef41Sopenharmony_ci !object()->accept_any_receiver())) { 15171cb0ef41Sopenharmony_ci return not_found; 15181cb0ef41Sopenharmony_ci } 15191cb0ef41Sopenharmony_ci 15201cb0ef41Sopenharmony_ci Handle<FunctionTemplateInfo> expected_receiver_type; 15211cb0ef41Sopenharmony_ci { 15221cb0ef41Sopenharmony_ci DisallowGarbageCollection no_gc; 15231cb0ef41Sopenharmony_ci HeapObject signature = object()->signature(); 15241cb0ef41Sopenharmony_ci if (signature.IsUndefined()) { 15251cb0ef41Sopenharmony_ci return HolderLookupResult(CallOptimization::kHolderIsReceiver); 15261cb0ef41Sopenharmony_ci } 15271cb0ef41Sopenharmony_ci expected_receiver_type = broker()->CanonicalPersistentHandle( 15281cb0ef41Sopenharmony_ci FunctionTemplateInfo::cast(signature)); 15291cb0ef41Sopenharmony_ci if (expected_receiver_type->IsTemplateFor(*receiver_map.object())) { 15301cb0ef41Sopenharmony_ci return HolderLookupResult(CallOptimization::kHolderIsReceiver); 15311cb0ef41Sopenharmony_ci } 15321cb0ef41Sopenharmony_ci if (!receiver_map.IsJSGlobalProxyMap()) return not_found; 15331cb0ef41Sopenharmony_ci } 15341cb0ef41Sopenharmony_ci 15351cb0ef41Sopenharmony_ci HeapObjectRef prototype = receiver_map.prototype(); 15361cb0ef41Sopenharmony_ci if (prototype.IsNull()) return not_found; 15371cb0ef41Sopenharmony_ci if (!expected_receiver_type->IsTemplateFor(prototype.object()->map())) { 15381cb0ef41Sopenharmony_ci return not_found; 15391cb0ef41Sopenharmony_ci } 15401cb0ef41Sopenharmony_ci return HolderLookupResult(CallOptimization::kHolderFound, 15411cb0ef41Sopenharmony_ci prototype.AsJSObject()); 15421cb0ef41Sopenharmony_ci} 15431cb0ef41Sopenharmony_ci 15441cb0ef41Sopenharmony_ciObjectRef CallHandlerInfoRef::data() const { 15451cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), object()->data()); 15461cb0ef41Sopenharmony_ci} 15471cb0ef41Sopenharmony_ci 15481cb0ef41Sopenharmony_ciHEAP_ACCESSOR_C(ScopeInfo, int, ContextLength) 15491cb0ef41Sopenharmony_ciHEAP_ACCESSOR_C(ScopeInfo, bool, HasContextExtensionSlot) 15501cb0ef41Sopenharmony_ciHEAP_ACCESSOR_C(ScopeInfo, bool, HasOuterScopeInfo) 15511cb0ef41Sopenharmony_ci 15521cb0ef41Sopenharmony_ciScopeInfoRef ScopeInfoRef::OuterScopeInfo() const { 15531cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), object()->OuterScopeInfo()); 15541cb0ef41Sopenharmony_ci} 15551cb0ef41Sopenharmony_ci 15561cb0ef41Sopenharmony_ciHEAP_ACCESSOR_C(SharedFunctionInfo, Builtin, builtin_id) 15571cb0ef41Sopenharmony_ci 15581cb0ef41Sopenharmony_ciBytecodeArrayRef SharedFunctionInfoRef::GetBytecodeArray() const { 15591cb0ef41Sopenharmony_ci CHECK(HasBytecodeArray()); 15601cb0ef41Sopenharmony_ci BytecodeArray bytecode_array; 15611cb0ef41Sopenharmony_ci if (!broker()->IsMainThread()) { 15621cb0ef41Sopenharmony_ci bytecode_array = object()->GetBytecodeArray(broker()->local_isolate()); 15631cb0ef41Sopenharmony_ci } else { 15641cb0ef41Sopenharmony_ci bytecode_array = object()->GetBytecodeArray(broker()->isolate()); 15651cb0ef41Sopenharmony_ci } 15661cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), bytecode_array); 15671cb0ef41Sopenharmony_ci} 15681cb0ef41Sopenharmony_ci 15691cb0ef41Sopenharmony_ci#define DEF_SFI_ACCESSOR(type, name) \ 15701cb0ef41Sopenharmony_ci HEAP_ACCESSOR_C(SharedFunctionInfo, type, name) 15711cb0ef41Sopenharmony_ciBROKER_SFI_FIELDS(DEF_SFI_ACCESSOR) 15721cb0ef41Sopenharmony_ci#undef DEF_SFI_ACCESSOR 15731cb0ef41Sopenharmony_ci 15741cb0ef41Sopenharmony_ciSharedFunctionInfo::Inlineability SharedFunctionInfoRef::GetInlineability() 15751cb0ef41Sopenharmony_ci const { 15761cb0ef41Sopenharmony_ci return broker()->IsMainThread() 15771cb0ef41Sopenharmony_ci ? object()->GetInlineability(broker()->isolate()) 15781cb0ef41Sopenharmony_ci : object()->GetInlineability(broker()->local_isolate()); 15791cb0ef41Sopenharmony_ci} 15801cb0ef41Sopenharmony_ci 15811cb0ef41Sopenharmony_ciObjectRef FeedbackCellRef::value() const { 15821cb0ef41Sopenharmony_ci DCHECK(data_->should_access_heap()); 15831cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), object()->value(kAcquireLoad)); 15841cb0ef41Sopenharmony_ci} 15851cb0ef41Sopenharmony_ci 15861cb0ef41Sopenharmony_cibase::Optional<ObjectRef> MapRef::GetStrongValue( 15871cb0ef41Sopenharmony_ci InternalIndex descriptor_index) const { 15881cb0ef41Sopenharmony_ci CHECK_LT(descriptor_index.as_int(), NumberOfOwnDescriptors()); 15891cb0ef41Sopenharmony_ci return instance_descriptors().GetStrongValue(descriptor_index); 15901cb0ef41Sopenharmony_ci} 15911cb0ef41Sopenharmony_ci 15921cb0ef41Sopenharmony_ciDescriptorArrayRef MapRef::instance_descriptors() const { 15931cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence( 15941cb0ef41Sopenharmony_ci broker(), 15951cb0ef41Sopenharmony_ci object()->instance_descriptors(broker()->isolate(), kAcquireLoad)); 15961cb0ef41Sopenharmony_ci} 15971cb0ef41Sopenharmony_ci 15981cb0ef41Sopenharmony_ciHeapObjectRef MapRef::prototype() const { 15991cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), 16001cb0ef41Sopenharmony_ci HeapObject::cast(object()->prototype())); 16011cb0ef41Sopenharmony_ci} 16021cb0ef41Sopenharmony_ci 16031cb0ef41Sopenharmony_ciMapRef MapRef::FindRootMap() const { 16041cb0ef41Sopenharmony_ci // TODO(solanes, v8:7790): Consider caching the result of the root map. 16051cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), 16061cb0ef41Sopenharmony_ci object()->FindRootMap(broker()->isolate())); 16071cb0ef41Sopenharmony_ci} 16081cb0ef41Sopenharmony_ci 16091cb0ef41Sopenharmony_ciObjectRef MapRef::GetConstructor() const { 16101cb0ef41Sopenharmony_ci // Immutable after initialization. 16111cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), object()->GetConstructor()); 16121cb0ef41Sopenharmony_ci} 16131cb0ef41Sopenharmony_ci 16141cb0ef41Sopenharmony_ciHeapObjectRef MapRef::GetBackPointer() const { 16151cb0ef41Sopenharmony_ci // Immutable after initialization. 16161cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), 16171cb0ef41Sopenharmony_ci HeapObject::cast(object()->GetBackPointer())); 16181cb0ef41Sopenharmony_ci} 16191cb0ef41Sopenharmony_ci 16201cb0ef41Sopenharmony_cibool JSTypedArrayRef::is_on_heap() const { 16211cb0ef41Sopenharmony_ci // Underlying field written 1. during initialization or 2. with release-store. 16221cb0ef41Sopenharmony_ci return object()->is_on_heap(kAcquireLoad); 16231cb0ef41Sopenharmony_ci} 16241cb0ef41Sopenharmony_ci 16251cb0ef41Sopenharmony_cisize_t JSTypedArrayRef::length() const { 16261cb0ef41Sopenharmony_ci CHECK(!is_on_heap()); 16271cb0ef41Sopenharmony_ci // Immutable after initialization. 16281cb0ef41Sopenharmony_ci return object()->length(); 16291cb0ef41Sopenharmony_ci} 16301cb0ef41Sopenharmony_ci 16311cb0ef41Sopenharmony_ciHeapObjectRef JSTypedArrayRef::buffer() const { 16321cb0ef41Sopenharmony_ci CHECK(!is_on_heap()); 16331cb0ef41Sopenharmony_ci // Immutable after initialization. 16341cb0ef41Sopenharmony_ci return MakeRef<HeapObject>(broker(), object()->buffer()); 16351cb0ef41Sopenharmony_ci} 16361cb0ef41Sopenharmony_ci 16371cb0ef41Sopenharmony_civoid* JSTypedArrayRef::data_ptr() const { 16381cb0ef41Sopenharmony_ci CHECK(!is_on_heap()); 16391cb0ef41Sopenharmony_ci // Underlying field written 1. during initialization or 2. protected by the 16401cb0ef41Sopenharmony_ci // is_on_heap release/acquire semantics (external_pointer store happens-before 16411cb0ef41Sopenharmony_ci // base_pointer store, and this external_pointer load happens-after 16421cb0ef41Sopenharmony_ci // base_pointer load). 16431cb0ef41Sopenharmony_ci STATIC_ASSERT(JSTypedArray::kOffHeapDataPtrEqualsExternalPointer); 16441cb0ef41Sopenharmony_ci return object()->DataPtr(); 16451cb0ef41Sopenharmony_ci} 16461cb0ef41Sopenharmony_ci 16471cb0ef41Sopenharmony_cibool MapRef::IsInobjectSlackTrackingInProgress() const { 16481cb0ef41Sopenharmony_ci return object()->IsInobjectSlackTrackingInProgress(); 16491cb0ef41Sopenharmony_ci} 16501cb0ef41Sopenharmony_ci 16511cb0ef41Sopenharmony_ciint MapRef::constructor_function_index() const { 16521cb0ef41Sopenharmony_ci return object()->GetConstructorFunctionIndex(); 16531cb0ef41Sopenharmony_ci} 16541cb0ef41Sopenharmony_ci 16551cb0ef41Sopenharmony_cibool MapRef::is_stable() const { 16561cb0ef41Sopenharmony_ci IF_ACCESS_FROM_HEAP_C(is_stable); 16571cb0ef41Sopenharmony_ci return !Map::Bits3::IsUnstableBit::decode(data()->AsMap()->bit_field3()); 16581cb0ef41Sopenharmony_ci} 16591cb0ef41Sopenharmony_ci 16601cb0ef41Sopenharmony_cibool MapRef::CanBeDeprecated() const { return object()->CanBeDeprecated(); } 16611cb0ef41Sopenharmony_ci 16621cb0ef41Sopenharmony_cibool MapRef::CanTransition() const { return object()->CanTransition(); } 16631cb0ef41Sopenharmony_ci 16641cb0ef41Sopenharmony_ciint MapRef::GetInObjectPropertiesStartInWords() const { 16651cb0ef41Sopenharmony_ci return object()->GetInObjectPropertiesStartInWords(); 16661cb0ef41Sopenharmony_ci} 16671cb0ef41Sopenharmony_ci 16681cb0ef41Sopenharmony_ciint MapRef::GetInObjectProperties() const { 16691cb0ef41Sopenharmony_ci IF_ACCESS_FROM_HEAP_C(GetInObjectProperties); 16701cb0ef41Sopenharmony_ci return data()->AsMap()->in_object_properties(); 16711cb0ef41Sopenharmony_ci} 16721cb0ef41Sopenharmony_ci 16731cb0ef41Sopenharmony_cibool StringRef::IsExternalString() const { 16741cb0ef41Sopenharmony_ci return object()->IsExternalString(); 16751cb0ef41Sopenharmony_ci} 16761cb0ef41Sopenharmony_ci 16771cb0ef41Sopenharmony_ciAddress CallHandlerInfoRef::callback() const { 16781cb0ef41Sopenharmony_ci return v8::ToCData<Address>(object()->callback()); 16791cb0ef41Sopenharmony_ci} 16801cb0ef41Sopenharmony_ci 16811cb0ef41Sopenharmony_ciZoneVector<Address> FunctionTemplateInfoRef::c_functions() const { 16821cb0ef41Sopenharmony_ci return GetCFunctions(FixedArray::cast(object()->GetCFunctionOverloads()), 16831cb0ef41Sopenharmony_ci broker()->zone()); 16841cb0ef41Sopenharmony_ci} 16851cb0ef41Sopenharmony_ci 16861cb0ef41Sopenharmony_ciZoneVector<const CFunctionInfo*> FunctionTemplateInfoRef::c_signatures() const { 16871cb0ef41Sopenharmony_ci return GetCSignatures(FixedArray::cast(object()->GetCFunctionOverloads()), 16881cb0ef41Sopenharmony_ci broker()->zone()); 16891cb0ef41Sopenharmony_ci} 16901cb0ef41Sopenharmony_ci 16911cb0ef41Sopenharmony_cibool StringRef::IsSeqString() const { return object()->IsSeqString(); } 16921cb0ef41Sopenharmony_ci 16931cb0ef41Sopenharmony_ciScopeInfoRef NativeContextRef::scope_info() const { 16941cb0ef41Sopenharmony_ci // The scope_info is immutable after initialization. 16951cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), object()->scope_info()); 16961cb0ef41Sopenharmony_ci} 16971cb0ef41Sopenharmony_ci 16981cb0ef41Sopenharmony_ciMapRef NativeContextRef::GetFunctionMapFromIndex(int index) const { 16991cb0ef41Sopenharmony_ci DCHECK_GE(index, Context::FIRST_FUNCTION_MAP_INDEX); 17001cb0ef41Sopenharmony_ci DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX); 17011cb0ef41Sopenharmony_ci CHECK_LT(index, object()->length()); 17021cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence( 17031cb0ef41Sopenharmony_ci broker(), Map::cast(object()->get(index, kAcquireLoad))); 17041cb0ef41Sopenharmony_ci} 17051cb0ef41Sopenharmony_ci 17061cb0ef41Sopenharmony_ciMapRef NativeContextRef::GetInitialJSArrayMap(ElementsKind kind) const { 17071cb0ef41Sopenharmony_ci switch (kind) { 17081cb0ef41Sopenharmony_ci case PACKED_SMI_ELEMENTS: 17091cb0ef41Sopenharmony_ci return js_array_packed_smi_elements_map(); 17101cb0ef41Sopenharmony_ci case HOLEY_SMI_ELEMENTS: 17111cb0ef41Sopenharmony_ci return js_array_holey_smi_elements_map(); 17121cb0ef41Sopenharmony_ci case PACKED_DOUBLE_ELEMENTS: 17131cb0ef41Sopenharmony_ci return js_array_packed_double_elements_map(); 17141cb0ef41Sopenharmony_ci case HOLEY_DOUBLE_ELEMENTS: 17151cb0ef41Sopenharmony_ci return js_array_holey_double_elements_map(); 17161cb0ef41Sopenharmony_ci case PACKED_ELEMENTS: 17171cb0ef41Sopenharmony_ci return js_array_packed_elements_map(); 17181cb0ef41Sopenharmony_ci case HOLEY_ELEMENTS: 17191cb0ef41Sopenharmony_ci return js_array_holey_elements_map(); 17201cb0ef41Sopenharmony_ci default: 17211cb0ef41Sopenharmony_ci UNREACHABLE(); 17221cb0ef41Sopenharmony_ci } 17231cb0ef41Sopenharmony_ci} 17241cb0ef41Sopenharmony_ci 17251cb0ef41Sopenharmony_ci#define DEF_NATIVE_CONTEXT_ACCESSOR(ResultType, Name) \ 17261cb0ef41Sopenharmony_ci ResultType##Ref NativeContextRef::Name() const { \ 17271cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence( \ 17281cb0ef41Sopenharmony_ci broker(), ResultType::cast(object()->Name(kAcquireLoad))); \ 17291cb0ef41Sopenharmony_ci } 17301cb0ef41Sopenharmony_ciBROKER_NATIVE_CONTEXT_FIELDS(DEF_NATIVE_CONTEXT_ACCESSOR) 17311cb0ef41Sopenharmony_ci#undef DEF_NATIVE_CONTEXT_ACCESSOR 17321cb0ef41Sopenharmony_ci 17331cb0ef41Sopenharmony_cibase::Optional<JSFunctionRef> NativeContextRef::GetConstructorFunction( 17341cb0ef41Sopenharmony_ci const MapRef& map) const { 17351cb0ef41Sopenharmony_ci CHECK(map.IsPrimitiveMap()); 17361cb0ef41Sopenharmony_ci switch (map.constructor_function_index()) { 17371cb0ef41Sopenharmony_ci case Map::kNoConstructorFunctionIndex: 17381cb0ef41Sopenharmony_ci return base::nullopt; 17391cb0ef41Sopenharmony_ci case Context::BIGINT_FUNCTION_INDEX: 17401cb0ef41Sopenharmony_ci return bigint_function(); 17411cb0ef41Sopenharmony_ci case Context::BOOLEAN_FUNCTION_INDEX: 17421cb0ef41Sopenharmony_ci return boolean_function(); 17431cb0ef41Sopenharmony_ci case Context::NUMBER_FUNCTION_INDEX: 17441cb0ef41Sopenharmony_ci return number_function(); 17451cb0ef41Sopenharmony_ci case Context::STRING_FUNCTION_INDEX: 17461cb0ef41Sopenharmony_ci return string_function(); 17471cb0ef41Sopenharmony_ci case Context::SYMBOL_FUNCTION_INDEX: 17481cb0ef41Sopenharmony_ci return symbol_function(); 17491cb0ef41Sopenharmony_ci default: 17501cb0ef41Sopenharmony_ci UNREACHABLE(); 17511cb0ef41Sopenharmony_ci } 17521cb0ef41Sopenharmony_ci} 17531cb0ef41Sopenharmony_ci 17541cb0ef41Sopenharmony_cibool ObjectRef::IsNull() const { return object()->IsNull(); } 17551cb0ef41Sopenharmony_ci 17561cb0ef41Sopenharmony_cibool ObjectRef::IsNullOrUndefined() const { 17571cb0ef41Sopenharmony_ci if (IsSmi()) return false; 17581cb0ef41Sopenharmony_ci OddballType type = AsHeapObject().map().oddball_type(); 17591cb0ef41Sopenharmony_ci return type == OddballType::kNull || type == OddballType::kUndefined; 17601cb0ef41Sopenharmony_ci} 17611cb0ef41Sopenharmony_ci 17621cb0ef41Sopenharmony_cibool ObjectRef::IsTheHole() const { 17631cb0ef41Sopenharmony_ci return IsHeapObject() && 17641cb0ef41Sopenharmony_ci AsHeapObject().map().oddball_type() == OddballType::kHole; 17651cb0ef41Sopenharmony_ci} 17661cb0ef41Sopenharmony_ci 17671cb0ef41Sopenharmony_cibase::Optional<bool> ObjectRef::TryGetBooleanValue() const { 17681cb0ef41Sopenharmony_ci if (data_->should_access_heap()) { 17691cb0ef41Sopenharmony_ci return object()->BooleanValue(broker()->isolate()); 17701cb0ef41Sopenharmony_ci } 17711cb0ef41Sopenharmony_ci if (IsSmi()) return AsSmi() != 0; 17721cb0ef41Sopenharmony_ci return data()->AsHeapObject()->TryGetBooleanValue(broker()); 17731cb0ef41Sopenharmony_ci} 17741cb0ef41Sopenharmony_ci 17751cb0ef41Sopenharmony_ciMaybe<double> ObjectRef::OddballToNumber() const { 17761cb0ef41Sopenharmony_ci OddballType type = AsHeapObject().map().oddball_type(); 17771cb0ef41Sopenharmony_ci 17781cb0ef41Sopenharmony_ci switch (type) { 17791cb0ef41Sopenharmony_ci case OddballType::kBoolean: { 17801cb0ef41Sopenharmony_ci ObjectRef true_ref = MakeRef<Object>( 17811cb0ef41Sopenharmony_ci broker(), broker()->isolate()->factory()->true_value()); 17821cb0ef41Sopenharmony_ci return this->equals(true_ref) ? Just(1.0) : Just(0.0); 17831cb0ef41Sopenharmony_ci } 17841cb0ef41Sopenharmony_ci case OddballType::kUndefined: { 17851cb0ef41Sopenharmony_ci return Just(std::numeric_limits<double>::quiet_NaN()); 17861cb0ef41Sopenharmony_ci } 17871cb0ef41Sopenharmony_ci case OddballType::kNull: { 17881cb0ef41Sopenharmony_ci return Just(0.0); 17891cb0ef41Sopenharmony_ci } 17901cb0ef41Sopenharmony_ci default: { 17911cb0ef41Sopenharmony_ci return Nothing<double>(); 17921cb0ef41Sopenharmony_ci } 17931cb0ef41Sopenharmony_ci } 17941cb0ef41Sopenharmony_ci} 17951cb0ef41Sopenharmony_ci 17961cb0ef41Sopenharmony_cibool ObjectRef::should_access_heap() const { 17971cb0ef41Sopenharmony_ci return data()->should_access_heap(); 17981cb0ef41Sopenharmony_ci} 17991cb0ef41Sopenharmony_ci 18001cb0ef41Sopenharmony_cibase::Optional<ObjectRef> JSObjectRef::GetOwnConstantElement( 18011cb0ef41Sopenharmony_ci const FixedArrayBaseRef& elements_ref, uint32_t index, 18021cb0ef41Sopenharmony_ci CompilationDependencies* dependencies) const { 18031cb0ef41Sopenharmony_ci base::Optional<Object> maybe_element = GetOwnConstantElementFromHeap( 18041cb0ef41Sopenharmony_ci *elements_ref.object(), map().elements_kind(), index); 18051cb0ef41Sopenharmony_ci if (!maybe_element.has_value()) return {}; 18061cb0ef41Sopenharmony_ci 18071cb0ef41Sopenharmony_ci base::Optional<ObjectRef> result = 18081cb0ef41Sopenharmony_ci TryMakeRef(broker(), maybe_element.value()); 18091cb0ef41Sopenharmony_ci if (result.has_value()) { 18101cb0ef41Sopenharmony_ci dependencies->DependOnOwnConstantElement(*this, index, *result); 18111cb0ef41Sopenharmony_ci } 18121cb0ef41Sopenharmony_ci return result; 18131cb0ef41Sopenharmony_ci} 18141cb0ef41Sopenharmony_ci 18151cb0ef41Sopenharmony_cibase::Optional<Object> JSObjectRef::GetOwnConstantElementFromHeap( 18161cb0ef41Sopenharmony_ci FixedArrayBase elements, ElementsKind elements_kind, uint32_t index) const { 18171cb0ef41Sopenharmony_ci DCHECK_LE(index, JSObject::kMaxElementIndex); 18181cb0ef41Sopenharmony_ci 18191cb0ef41Sopenharmony_ci Handle<JSObject> holder = object(); 18201cb0ef41Sopenharmony_ci 18211cb0ef41Sopenharmony_ci // This block is carefully constructed to avoid Ref creation and access since 18221cb0ef41Sopenharmony_ci // this method may be called after the broker has retired. 18231cb0ef41Sopenharmony_ci // The relaxed `length` read is safe to use in this case since: 18241cb0ef41Sopenharmony_ci // - GetOwnConstantElement only detects a constant for JSArray holders if 18251cb0ef41Sopenharmony_ci // the array is frozen/sealed. 18261cb0ef41Sopenharmony_ci // - Frozen/sealed arrays can't change length. 18271cb0ef41Sopenharmony_ci // - We've already seen a map with frozen/sealed elements_kinds (above); 18281cb0ef41Sopenharmony_ci // - The release-load of that map ensures we read the newest value 18291cb0ef41Sopenharmony_ci // of `length` below. 18301cb0ef41Sopenharmony_ci if (holder->IsJSArray()) { 18311cb0ef41Sopenharmony_ci uint32_t array_length; 18321cb0ef41Sopenharmony_ci if (!JSArray::cast(*holder) 18331cb0ef41Sopenharmony_ci .length(broker()->isolate(), kRelaxedLoad) 18341cb0ef41Sopenharmony_ci .ToArrayLength(&array_length)) { 18351cb0ef41Sopenharmony_ci return {}; 18361cb0ef41Sopenharmony_ci } 18371cb0ef41Sopenharmony_ci // See also ElementsAccessorBase::GetMaxIndex. 18381cb0ef41Sopenharmony_ci if (index >= array_length) return {}; 18391cb0ef41Sopenharmony_ci } 18401cb0ef41Sopenharmony_ci 18411cb0ef41Sopenharmony_ci Object maybe_element; 18421cb0ef41Sopenharmony_ci auto result = ConcurrentLookupIterator::TryGetOwnConstantElement( 18431cb0ef41Sopenharmony_ci &maybe_element, broker()->isolate(), broker()->local_isolate(), *holder, 18441cb0ef41Sopenharmony_ci elements, elements_kind, index); 18451cb0ef41Sopenharmony_ci 18461cb0ef41Sopenharmony_ci if (result == ConcurrentLookupIterator::kGaveUp) { 18471cb0ef41Sopenharmony_ci TRACE_BROKER_MISSING(broker(), "JSObject::GetOwnConstantElement on " 18481cb0ef41Sopenharmony_ci << *this << " at index " << index); 18491cb0ef41Sopenharmony_ci return {}; 18501cb0ef41Sopenharmony_ci } else if (result == ConcurrentLookupIterator::kNotPresent) { 18511cb0ef41Sopenharmony_ci return {}; 18521cb0ef41Sopenharmony_ci } 18531cb0ef41Sopenharmony_ci 18541cb0ef41Sopenharmony_ci DCHECK_EQ(result, ConcurrentLookupIterator::kPresent); 18551cb0ef41Sopenharmony_ci return maybe_element; 18561cb0ef41Sopenharmony_ci} 18571cb0ef41Sopenharmony_ci 18581cb0ef41Sopenharmony_cibase::Optional<ObjectRef> JSObjectRef::GetOwnFastDataProperty( 18591cb0ef41Sopenharmony_ci Representation field_representation, FieldIndex index, 18601cb0ef41Sopenharmony_ci CompilationDependencies* dependencies) const { 18611cb0ef41Sopenharmony_ci base::Optional<ObjectRef> result = GetOwnFastDataPropertyFromHeap( 18621cb0ef41Sopenharmony_ci broker(), *this, field_representation, index); 18631cb0ef41Sopenharmony_ci if (result.has_value()) { 18641cb0ef41Sopenharmony_ci dependencies->DependOnOwnConstantDataProperty( 18651cb0ef41Sopenharmony_ci *this, map(), field_representation, index, *result); 18661cb0ef41Sopenharmony_ci } 18671cb0ef41Sopenharmony_ci return result; 18681cb0ef41Sopenharmony_ci} 18691cb0ef41Sopenharmony_ci 18701cb0ef41Sopenharmony_cibase::Optional<ObjectRef> JSObjectRef::GetOwnDictionaryProperty( 18711cb0ef41Sopenharmony_ci InternalIndex index, CompilationDependencies* dependencies) const { 18721cb0ef41Sopenharmony_ci CHECK(index.is_found()); 18731cb0ef41Sopenharmony_ci base::Optional<ObjectRef> result = 18741cb0ef41Sopenharmony_ci GetOwnDictionaryPropertyFromHeap(broker(), object(), index); 18751cb0ef41Sopenharmony_ci if (result.has_value()) { 18761cb0ef41Sopenharmony_ci dependencies->DependOnOwnConstantDictionaryProperty(*this, index, *result); 18771cb0ef41Sopenharmony_ci } 18781cb0ef41Sopenharmony_ci return result; 18791cb0ef41Sopenharmony_ci} 18801cb0ef41Sopenharmony_ci 18811cb0ef41Sopenharmony_ciObjectRef JSArrayRef::GetBoilerplateLength() const { 18821cb0ef41Sopenharmony_ci // Safe to read concurrently because: 18831cb0ef41Sopenharmony_ci // - boilerplates are immutable after initialization. 18841cb0ef41Sopenharmony_ci // - boilerplates are published into the feedback vector. 18851cb0ef41Sopenharmony_ci // These facts also mean we can expect a valid value. 18861cb0ef41Sopenharmony_ci return length_unsafe().value(); 18871cb0ef41Sopenharmony_ci} 18881cb0ef41Sopenharmony_ci 18891cb0ef41Sopenharmony_cibase::Optional<ObjectRef> JSArrayRef::length_unsafe() const { 18901cb0ef41Sopenharmony_ci return TryMakeRef(broker(), 18911cb0ef41Sopenharmony_ci object()->length(broker()->isolate(), kRelaxedLoad)); 18921cb0ef41Sopenharmony_ci} 18931cb0ef41Sopenharmony_ci 18941cb0ef41Sopenharmony_cibase::Optional<ObjectRef> JSArrayRef::GetOwnCowElement( 18951cb0ef41Sopenharmony_ci FixedArrayBaseRef elements_ref, uint32_t index) const { 18961cb0ef41Sopenharmony_ci // Note: we'd like to check `elements_ref == elements()` here, but due to 18971cb0ef41Sopenharmony_ci // concurrency this may not hold. The code below must be able to deal with 18981cb0ef41Sopenharmony_ci // concurrent `elements` modifications. 18991cb0ef41Sopenharmony_ci 19001cb0ef41Sopenharmony_ci // Due to concurrency, the kind read here may not be consistent with 19011cb0ef41Sopenharmony_ci // `elements_ref`. The caller has to guarantee consistency at runtime by 19021cb0ef41Sopenharmony_ci // other means (e.g. through a runtime equality check or a compilation 19031cb0ef41Sopenharmony_ci // dependency). 19041cb0ef41Sopenharmony_ci ElementsKind elements_kind = map().elements_kind(); 19051cb0ef41Sopenharmony_ci 19061cb0ef41Sopenharmony_ci // We only inspect fixed COW arrays, which may only occur for fast 19071cb0ef41Sopenharmony_ci // smi/objects elements kinds. 19081cb0ef41Sopenharmony_ci if (!IsSmiOrObjectElementsKind(elements_kind)) return {}; 19091cb0ef41Sopenharmony_ci DCHECK(IsFastElementsKind(elements_kind)); 19101cb0ef41Sopenharmony_ci if (!elements_ref.map().IsFixedCowArrayMap()) return {}; 19111cb0ef41Sopenharmony_ci 19121cb0ef41Sopenharmony_ci // As the name says, the `length` read here is unsafe and may not match 19131cb0ef41Sopenharmony_ci // `elements`. We rely on the invariant that any `length` change will 19141cb0ef41Sopenharmony_ci // also result in an `elements` change to make this safe. The `elements` 19151cb0ef41Sopenharmony_ci // consistency check in the caller thus also guards the value of `length`. 19161cb0ef41Sopenharmony_ci base::Optional<ObjectRef> length_ref = length_unsafe(); 19171cb0ef41Sopenharmony_ci 19181cb0ef41Sopenharmony_ci if (!length_ref.has_value()) return {}; 19191cb0ef41Sopenharmony_ci 19201cb0ef41Sopenharmony_ci // Likewise we only deal with smi lengths. 19211cb0ef41Sopenharmony_ci if (!length_ref->IsSmi()) return {}; 19221cb0ef41Sopenharmony_ci 19231cb0ef41Sopenharmony_ci base::Optional<Object> result = ConcurrentLookupIterator::TryGetOwnCowElement( 19241cb0ef41Sopenharmony_ci broker()->isolate(), *elements_ref.AsFixedArray().object(), elements_kind, 19251cb0ef41Sopenharmony_ci length_ref->AsSmi(), index); 19261cb0ef41Sopenharmony_ci if (!result.has_value()) return {}; 19271cb0ef41Sopenharmony_ci 19281cb0ef41Sopenharmony_ci return TryMakeRef(broker(), result.value()); 19291cb0ef41Sopenharmony_ci} 19301cb0ef41Sopenharmony_ci 19311cb0ef41Sopenharmony_cibase::Optional<CellRef> SourceTextModuleRef::GetCell(int cell_index) const { 19321cb0ef41Sopenharmony_ci return TryMakeRef(broker(), object()->GetCell(cell_index)); 19331cb0ef41Sopenharmony_ci} 19341cb0ef41Sopenharmony_ci 19351cb0ef41Sopenharmony_cibase::Optional<ObjectRef> SourceTextModuleRef::import_meta() const { 19361cb0ef41Sopenharmony_ci return TryMakeRef(broker(), object()->import_meta(kAcquireLoad)); 19371cb0ef41Sopenharmony_ci} 19381cb0ef41Sopenharmony_ci 19391cb0ef41Sopenharmony_cibase::Optional<MapRef> HeapObjectRef::map_direct_read() const { 19401cb0ef41Sopenharmony_ci PtrComprCageBase cage_base = broker()->cage_base(); 19411cb0ef41Sopenharmony_ci return TryMakeRef(broker(), object()->map(cage_base, kAcquireLoad), 19421cb0ef41Sopenharmony_ci kAssumeMemoryFence); 19431cb0ef41Sopenharmony_ci} 19441cb0ef41Sopenharmony_ci 19451cb0ef41Sopenharmony_cinamespace { 19461cb0ef41Sopenharmony_ci 19471cb0ef41Sopenharmony_ciOddballType GetOddballType(Isolate* isolate, Map map) { 19481cb0ef41Sopenharmony_ci if (map.instance_type() != ODDBALL_TYPE) { 19491cb0ef41Sopenharmony_ci return OddballType::kNone; 19501cb0ef41Sopenharmony_ci } 19511cb0ef41Sopenharmony_ci ReadOnlyRoots roots(isolate); 19521cb0ef41Sopenharmony_ci if (map == roots.undefined_map()) { 19531cb0ef41Sopenharmony_ci return OddballType::kUndefined; 19541cb0ef41Sopenharmony_ci } 19551cb0ef41Sopenharmony_ci if (map == roots.null_map()) { 19561cb0ef41Sopenharmony_ci return OddballType::kNull; 19571cb0ef41Sopenharmony_ci } 19581cb0ef41Sopenharmony_ci if (map == roots.boolean_map()) { 19591cb0ef41Sopenharmony_ci return OddballType::kBoolean; 19601cb0ef41Sopenharmony_ci } 19611cb0ef41Sopenharmony_ci if (map == roots.the_hole_map()) { 19621cb0ef41Sopenharmony_ci return OddballType::kHole; 19631cb0ef41Sopenharmony_ci } 19641cb0ef41Sopenharmony_ci if (map == roots.uninitialized_map()) { 19651cb0ef41Sopenharmony_ci return OddballType::kUninitialized; 19661cb0ef41Sopenharmony_ci } 19671cb0ef41Sopenharmony_ci DCHECK(map == roots.termination_exception_map() || 19681cb0ef41Sopenharmony_ci map == roots.arguments_marker_map() || 19691cb0ef41Sopenharmony_ci map == roots.optimized_out_map() || map == roots.stale_register_map()); 19701cb0ef41Sopenharmony_ci return OddballType::kOther; 19711cb0ef41Sopenharmony_ci} 19721cb0ef41Sopenharmony_ci 19731cb0ef41Sopenharmony_ci} // namespace 19741cb0ef41Sopenharmony_ci 19751cb0ef41Sopenharmony_ciHeapObjectType HeapObjectRef::GetHeapObjectType() const { 19761cb0ef41Sopenharmony_ci if (data_->should_access_heap()) { 19771cb0ef41Sopenharmony_ci Map map = Handle<HeapObject>::cast(object())->map(broker()->cage_base()); 19781cb0ef41Sopenharmony_ci HeapObjectType::Flags flags(0); 19791cb0ef41Sopenharmony_ci if (map.is_undetectable()) flags |= HeapObjectType::kUndetectable; 19801cb0ef41Sopenharmony_ci if (map.is_callable()) flags |= HeapObjectType::kCallable; 19811cb0ef41Sopenharmony_ci return HeapObjectType(map.instance_type(), flags, 19821cb0ef41Sopenharmony_ci GetOddballType(broker()->isolate(), map)); 19831cb0ef41Sopenharmony_ci } 19841cb0ef41Sopenharmony_ci HeapObjectType::Flags flags(0); 19851cb0ef41Sopenharmony_ci if (map().is_undetectable()) flags |= HeapObjectType::kUndetectable; 19861cb0ef41Sopenharmony_ci if (map().is_callable()) flags |= HeapObjectType::kCallable; 19871cb0ef41Sopenharmony_ci return HeapObjectType(map().instance_type(), flags, map().oddball_type()); 19881cb0ef41Sopenharmony_ci} 19891cb0ef41Sopenharmony_ci 19901cb0ef41Sopenharmony_cibase::Optional<JSObjectRef> AllocationSiteRef::boilerplate() const { 19911cb0ef41Sopenharmony_ci if (!PointsToLiteral()) return {}; 19921cb0ef41Sopenharmony_ci DCHECK(data_->should_access_heap()); 19931cb0ef41Sopenharmony_ci return TryMakeRef(broker(), object()->boilerplate(kAcquireLoad)); 19941cb0ef41Sopenharmony_ci} 19951cb0ef41Sopenharmony_ci 19961cb0ef41Sopenharmony_cibase::Optional<FixedArrayBaseRef> JSObjectRef::elements( 19971cb0ef41Sopenharmony_ci RelaxedLoadTag tag) const { 19981cb0ef41Sopenharmony_ci return TryMakeRef(broker(), object()->elements(tag)); 19991cb0ef41Sopenharmony_ci} 20001cb0ef41Sopenharmony_ci 20011cb0ef41Sopenharmony_ciint FixedArrayBaseRef::length() const { 20021cb0ef41Sopenharmony_ci IF_ACCESS_FROM_HEAP_C(length); 20031cb0ef41Sopenharmony_ci return data()->AsFixedArrayBase()->length(); 20041cb0ef41Sopenharmony_ci} 20051cb0ef41Sopenharmony_ci 20061cb0ef41Sopenharmony_ciPropertyDetails DescriptorArrayRef::GetPropertyDetails( 20071cb0ef41Sopenharmony_ci InternalIndex descriptor_index) const { 20081cb0ef41Sopenharmony_ci return object()->GetDetails(descriptor_index); 20091cb0ef41Sopenharmony_ci} 20101cb0ef41Sopenharmony_ci 20111cb0ef41Sopenharmony_ciNameRef DescriptorArrayRef::GetPropertyKey( 20121cb0ef41Sopenharmony_ci InternalIndex descriptor_index) const { 20131cb0ef41Sopenharmony_ci NameRef result = MakeRef(broker(), object()->GetKey(descriptor_index)); 20141cb0ef41Sopenharmony_ci CHECK(result.IsUniqueName()); 20151cb0ef41Sopenharmony_ci return result; 20161cb0ef41Sopenharmony_ci} 20171cb0ef41Sopenharmony_ci 20181cb0ef41Sopenharmony_cibase::Optional<ObjectRef> DescriptorArrayRef::GetStrongValue( 20191cb0ef41Sopenharmony_ci InternalIndex descriptor_index) const { 20201cb0ef41Sopenharmony_ci HeapObject heap_object; 20211cb0ef41Sopenharmony_ci if (!object() 20221cb0ef41Sopenharmony_ci ->GetValue(descriptor_index) 20231cb0ef41Sopenharmony_ci .GetHeapObjectIfStrong(&heap_object)) { 20241cb0ef41Sopenharmony_ci return {}; 20251cb0ef41Sopenharmony_ci } 20261cb0ef41Sopenharmony_ci // Since the descriptors in the descriptor array can be changed in-place 20271cb0ef41Sopenharmony_ci // via DescriptorArray::Replace, we might get a value that we haven't seen 20281cb0ef41Sopenharmony_ci // before. 20291cb0ef41Sopenharmony_ci return TryMakeRef(broker(), heap_object); 20301cb0ef41Sopenharmony_ci} 20311cb0ef41Sopenharmony_ci 20321cb0ef41Sopenharmony_cibase::Optional<FeedbackVectorRef> FeedbackCellRef::feedback_vector() const { 20331cb0ef41Sopenharmony_ci ObjectRef contents = value(); 20341cb0ef41Sopenharmony_ci if (!contents.IsFeedbackVector()) return {}; 20351cb0ef41Sopenharmony_ci return contents.AsFeedbackVector(); 20361cb0ef41Sopenharmony_ci} 20371cb0ef41Sopenharmony_ci 20381cb0ef41Sopenharmony_cibase::Optional<SharedFunctionInfoRef> FeedbackCellRef::shared_function_info() 20391cb0ef41Sopenharmony_ci const { 20401cb0ef41Sopenharmony_ci base::Optional<FeedbackVectorRef> vector = feedback_vector(); 20411cb0ef41Sopenharmony_ci if (!vector.has_value()) return {}; 20421cb0ef41Sopenharmony_ci return vector->shared_function_info(); 20431cb0ef41Sopenharmony_ci} 20441cb0ef41Sopenharmony_ci 20451cb0ef41Sopenharmony_ciSharedFunctionInfoRef FeedbackVectorRef::shared_function_info() const { 20461cb0ef41Sopenharmony_ci // Immutable after initialization. 20471cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), object()->shared_function_info()); 20481cb0ef41Sopenharmony_ci} 20491cb0ef41Sopenharmony_ci 20501cb0ef41Sopenharmony_cibool NameRef::IsUniqueName() const { 20511cb0ef41Sopenharmony_ci // Must match Name::IsUniqueName. 20521cb0ef41Sopenharmony_ci return IsInternalizedString() || IsSymbol(); 20531cb0ef41Sopenharmony_ci} 20541cb0ef41Sopenharmony_ci 20551cb0ef41Sopenharmony_ciHandle<Object> ObjectRef::object() const { 20561cb0ef41Sopenharmony_ci return data_->object(); 20571cb0ef41Sopenharmony_ci} 20581cb0ef41Sopenharmony_ci 20591cb0ef41Sopenharmony_ci#ifdef DEBUG 20601cb0ef41Sopenharmony_ci#define DEF_OBJECT_GETTER(T) \ 20611cb0ef41Sopenharmony_ci Handle<T> T##Ref::object() const { \ 20621cb0ef41Sopenharmony_ci return Handle<T>(reinterpret_cast<Address*>(data_->object().address())); \ 20631cb0ef41Sopenharmony_ci } 20641cb0ef41Sopenharmony_ci#else 20651cb0ef41Sopenharmony_ci#define DEF_OBJECT_GETTER(T) \ 20661cb0ef41Sopenharmony_ci Handle<T> T##Ref::object() const { \ 20671cb0ef41Sopenharmony_ci return Handle<T>(reinterpret_cast<Address*>(data_->object().address())); \ 20681cb0ef41Sopenharmony_ci } 20691cb0ef41Sopenharmony_ci#endif // DEBUG 20701cb0ef41Sopenharmony_ci 20711cb0ef41Sopenharmony_ciHEAP_BROKER_OBJECT_LIST(DEF_OBJECT_GETTER) 20721cb0ef41Sopenharmony_ci#undef DEF_OBJECT_GETTER 20731cb0ef41Sopenharmony_ci 20741cb0ef41Sopenharmony_ciJSHeapBroker* ObjectRef::broker() const { return broker_; } 20751cb0ef41Sopenharmony_ci 20761cb0ef41Sopenharmony_ciObjectData* ObjectRef::data() const { 20771cb0ef41Sopenharmony_ci switch (broker()->mode()) { 20781cb0ef41Sopenharmony_ci case JSHeapBroker::kDisabled: 20791cb0ef41Sopenharmony_ci return data_; 20801cb0ef41Sopenharmony_ci case JSHeapBroker::kSerializing: 20811cb0ef41Sopenharmony_ci CHECK_NE(data_->kind(), kUnserializedHeapObject); 20821cb0ef41Sopenharmony_ci return data_; 20831cb0ef41Sopenharmony_ci case JSHeapBroker::kSerialized: 20841cb0ef41Sopenharmony_ci case JSHeapBroker::kRetired: 20851cb0ef41Sopenharmony_ci CHECK_NE(data_->kind(), kUnserializedHeapObject); 20861cb0ef41Sopenharmony_ci return data_; 20871cb0ef41Sopenharmony_ci } 20881cb0ef41Sopenharmony_ci} 20891cb0ef41Sopenharmony_ci 20901cb0ef41Sopenharmony_citemplate <class T> 20911cb0ef41Sopenharmony_citypename TinyRef<T>::RefType TinyRef<T>::AsRef(JSHeapBroker* broker) const { 20921cb0ef41Sopenharmony_ci if (data_->kind() == kUnserializedHeapObject && 20931cb0ef41Sopenharmony_ci broker->mode() != JSHeapBroker::kDisabled) { 20941cb0ef41Sopenharmony_ci // Gotta reconstruct to avoid returning a stale unserialized ref. 20951cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence<T>(broker, 20961cb0ef41Sopenharmony_ci Handle<T>::cast(data_->object())); 20971cb0ef41Sopenharmony_ci } 20981cb0ef41Sopenharmony_ci return TryMakeRef<T>(broker, data_).value(); 20991cb0ef41Sopenharmony_ci} 21001cb0ef41Sopenharmony_ci 21011cb0ef41Sopenharmony_citemplate <class T> 21021cb0ef41Sopenharmony_ciHandle<T> TinyRef<T>::object() const { 21031cb0ef41Sopenharmony_ci return Handle<T>::cast(data_->object()); 21041cb0ef41Sopenharmony_ci} 21051cb0ef41Sopenharmony_ci 21061cb0ef41Sopenharmony_ci#define V(Name) \ 21071cb0ef41Sopenharmony_ci template class TinyRef<Name>; \ 21081cb0ef41Sopenharmony_ci /* TinyRef should contain only one pointer. */ \ 21091cb0ef41Sopenharmony_ci STATIC_ASSERT(sizeof(TinyRef<Name>) == kSystemPointerSize); 21101cb0ef41Sopenharmony_ciHEAP_BROKER_OBJECT_LIST(V) 21111cb0ef41Sopenharmony_ci#undef V 21121cb0ef41Sopenharmony_ci 21131cb0ef41Sopenharmony_ci#define JSFUNCTION_BIMODAL_ACCESSOR_WITH_DEP(Result, Name, UsedField) \ 21141cb0ef41Sopenharmony_ci Result##Ref JSFunctionRef::Name(CompilationDependencies* dependencies) \ 21151cb0ef41Sopenharmony_ci const { \ 21161cb0ef41Sopenharmony_ci IF_ACCESS_FROM_HEAP(Result, Name); \ 21171cb0ef41Sopenharmony_ci RecordConsistentJSFunctionViewDependencyIfNeeded( \ 21181cb0ef41Sopenharmony_ci broker(), *this, data()->AsJSFunction(), UsedField); \ 21191cb0ef41Sopenharmony_ci return Result##Ref(broker(), data()->AsJSFunction()->Name()); \ 21201cb0ef41Sopenharmony_ci } 21211cb0ef41Sopenharmony_ci 21221cb0ef41Sopenharmony_ci#define JSFUNCTION_BIMODAL_ACCESSOR_WITH_DEP_C(Result, Name, UsedField) \ 21231cb0ef41Sopenharmony_ci Result JSFunctionRef::Name(CompilationDependencies* dependencies) const { \ 21241cb0ef41Sopenharmony_ci IF_ACCESS_FROM_HEAP_C(Name); \ 21251cb0ef41Sopenharmony_ci RecordConsistentJSFunctionViewDependencyIfNeeded( \ 21261cb0ef41Sopenharmony_ci broker(), *this, data()->AsJSFunction(), UsedField); \ 21271cb0ef41Sopenharmony_ci return data()->AsJSFunction()->Name(); \ 21281cb0ef41Sopenharmony_ci } 21291cb0ef41Sopenharmony_ci 21301cb0ef41Sopenharmony_ci// Like JSFUNCTION_BIMODAL_ACCESSOR_WITH_DEP_C but only depend on the 21311cb0ef41Sopenharmony_ci// field in question if its recorded value is "relevant". This is in order to 21321cb0ef41Sopenharmony_ci// tolerate certain state changes during compilation, e.g. from "has no feedback 21331cb0ef41Sopenharmony_ci// vector" (in which case we would simply do less optimization) to "has feedback 21341cb0ef41Sopenharmony_ci// vector". 21351cb0ef41Sopenharmony_ci#define JSFUNCTION_BIMODAL_ACCESSOR_WITH_DEP_RELEVANT_C( \ 21361cb0ef41Sopenharmony_ci Result, Name, UsedField, RelevantValue) \ 21371cb0ef41Sopenharmony_ci Result JSFunctionRef::Name(CompilationDependencies* dependencies) const { \ 21381cb0ef41Sopenharmony_ci IF_ACCESS_FROM_HEAP_C(Name); \ 21391cb0ef41Sopenharmony_ci Result const result = data()->AsJSFunction()->Name(); \ 21401cb0ef41Sopenharmony_ci if (result == RelevantValue) { \ 21411cb0ef41Sopenharmony_ci RecordConsistentJSFunctionViewDependencyIfNeeded( \ 21421cb0ef41Sopenharmony_ci broker(), *this, data()->AsJSFunction(), UsedField); \ 21431cb0ef41Sopenharmony_ci } \ 21441cb0ef41Sopenharmony_ci return result; \ 21451cb0ef41Sopenharmony_ci } 21461cb0ef41Sopenharmony_ci 21471cb0ef41Sopenharmony_ciJSFUNCTION_BIMODAL_ACCESSOR_WITH_DEP_RELEVANT_C(bool, has_initial_map, 21481cb0ef41Sopenharmony_ci JSFunctionData::kHasInitialMap, 21491cb0ef41Sopenharmony_ci true) 21501cb0ef41Sopenharmony_ciJSFUNCTION_BIMODAL_ACCESSOR_WITH_DEP_RELEVANT_C( 21511cb0ef41Sopenharmony_ci bool, has_instance_prototype, JSFunctionData::kHasInstancePrototype, true) 21521cb0ef41Sopenharmony_ciJSFUNCTION_BIMODAL_ACCESSOR_WITH_DEP_RELEVANT_C( 21531cb0ef41Sopenharmony_ci bool, PrototypeRequiresRuntimeLookup, 21541cb0ef41Sopenharmony_ci JSFunctionData::kPrototypeRequiresRuntimeLookup, false) 21551cb0ef41Sopenharmony_ci 21561cb0ef41Sopenharmony_ciJSFUNCTION_BIMODAL_ACCESSOR_WITH_DEP(Map, initial_map, 21571cb0ef41Sopenharmony_ci JSFunctionData::kInitialMap) 21581cb0ef41Sopenharmony_ciJSFUNCTION_BIMODAL_ACCESSOR_WITH_DEP(Object, instance_prototype, 21591cb0ef41Sopenharmony_ci JSFunctionData::kInstancePrototype) 21601cb0ef41Sopenharmony_ciJSFUNCTION_BIMODAL_ACCESSOR_WITH_DEP(FeedbackCell, raw_feedback_cell, 21611cb0ef41Sopenharmony_ci JSFunctionData::kFeedbackCell) 21621cb0ef41Sopenharmony_ci 21631cb0ef41Sopenharmony_ciBIMODAL_ACCESSOR(JSFunction, Context, context) 21641cb0ef41Sopenharmony_ciBIMODAL_ACCESSOR(JSFunction, SharedFunctionInfo, shared) 21651cb0ef41Sopenharmony_ci 21661cb0ef41Sopenharmony_ci#undef JSFUNCTION_BIMODAL_ACCESSOR_WITH_DEP 21671cb0ef41Sopenharmony_ci#undef JSFUNCTION_BIMODAL_ACCESSOR_WITH_DEP_C 21681cb0ef41Sopenharmony_ci 21691cb0ef41Sopenharmony_ciCodeRef JSFunctionRef::code() const { 21701cb0ef41Sopenharmony_ci CodeT code = object()->code(kAcquireLoad); 21711cb0ef41Sopenharmony_ci // Safe to do a relaxed conversion to Code here since CodeT::code field is 21721cb0ef41Sopenharmony_ci // modified only by GC and the CodeT was acquire-loaded. 21731cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), FromCodeT(code, kRelaxedLoad)); 21741cb0ef41Sopenharmony_ci} 21751cb0ef41Sopenharmony_ci 21761cb0ef41Sopenharmony_ciNativeContextRef JSFunctionRef::native_context() const { 21771cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), 21781cb0ef41Sopenharmony_ci context().object()->native_context()); 21791cb0ef41Sopenharmony_ci} 21801cb0ef41Sopenharmony_ci 21811cb0ef41Sopenharmony_cibase::Optional<FunctionTemplateInfoRef> 21821cb0ef41Sopenharmony_ciSharedFunctionInfoRef::function_template_info() const { 21831cb0ef41Sopenharmony_ci if (!object()->IsApiFunction()) return {}; 21841cb0ef41Sopenharmony_ci return TryMakeRef(broker(), FunctionTemplateInfo::cast( 21851cb0ef41Sopenharmony_ci object()->function_data(kAcquireLoad))); 21861cb0ef41Sopenharmony_ci} 21871cb0ef41Sopenharmony_ci 21881cb0ef41Sopenharmony_ciint SharedFunctionInfoRef::context_header_size() const { 21891cb0ef41Sopenharmony_ci return object()->scope_info().ContextHeaderLength(); 21901cb0ef41Sopenharmony_ci} 21911cb0ef41Sopenharmony_ci 21921cb0ef41Sopenharmony_ciint SharedFunctionInfoRef::context_parameters_start() const { 21931cb0ef41Sopenharmony_ci return object()->scope_info().ParametersStartIndex(); 21941cb0ef41Sopenharmony_ci} 21951cb0ef41Sopenharmony_ci 21961cb0ef41Sopenharmony_ciScopeInfoRef SharedFunctionInfoRef::scope_info() const { 21971cb0ef41Sopenharmony_ci return MakeRefAssumeMemoryFence(broker(), object()->scope_info(kAcquireLoad)); 21981cb0ef41Sopenharmony_ci} 21991cb0ef41Sopenharmony_ci 22001cb0ef41Sopenharmony_cibase::Optional<MapRef> JSObjectRef::GetObjectCreateMap() const { 22011cb0ef41Sopenharmony_ci Handle<Map> map_handle = Handle<Map>::cast(map().object()); 22021cb0ef41Sopenharmony_ci // Note: implemented as an acquire-load. 22031cb0ef41Sopenharmony_ci if (!map_handle->is_prototype_map()) return {}; 22041cb0ef41Sopenharmony_ci 22051cb0ef41Sopenharmony_ci Handle<Object> maybe_proto_info = broker()->CanonicalPersistentHandle( 22061cb0ef41Sopenharmony_ci map_handle->prototype_info(kAcquireLoad)); 22071cb0ef41Sopenharmony_ci if (!maybe_proto_info->IsPrototypeInfo()) return {}; 22081cb0ef41Sopenharmony_ci 22091cb0ef41Sopenharmony_ci MaybeObject maybe_object_create_map = 22101cb0ef41Sopenharmony_ci Handle<PrototypeInfo>::cast(maybe_proto_info) 22111cb0ef41Sopenharmony_ci ->object_create_map(kAcquireLoad); 22121cb0ef41Sopenharmony_ci if (!maybe_object_create_map->IsWeak()) return {}; 22131cb0ef41Sopenharmony_ci 22141cb0ef41Sopenharmony_ci return MapRef(broker(), 22151cb0ef41Sopenharmony_ci broker()->GetOrCreateData( 22161cb0ef41Sopenharmony_ci maybe_object_create_map->GetHeapObjectAssumeWeak(), 22171cb0ef41Sopenharmony_ci kAssumeMemoryFence)); 22181cb0ef41Sopenharmony_ci} 22191cb0ef41Sopenharmony_ci 22201cb0ef41Sopenharmony_cibool PropertyCellRef::Cache() const { 22211cb0ef41Sopenharmony_ci if (data_->should_access_heap()) return true; 22221cb0ef41Sopenharmony_ci CHECK(broker()->mode() == JSHeapBroker::kSerializing || 22231cb0ef41Sopenharmony_ci broker()->mode() == JSHeapBroker::kSerialized); 22241cb0ef41Sopenharmony_ci return data()->AsPropertyCell()->Cache(broker()); 22251cb0ef41Sopenharmony_ci} 22261cb0ef41Sopenharmony_ci 22271cb0ef41Sopenharmony_cibool NativeContextRef::GlobalIsDetached() const { 22281cb0ef41Sopenharmony_ci ObjectRef proxy_proto = global_proxy_object().map().prototype(); 22291cb0ef41Sopenharmony_ci return !proxy_proto.equals(global_object()); 22301cb0ef41Sopenharmony_ci} 22311cb0ef41Sopenharmony_ci 22321cb0ef41Sopenharmony_cibase::Optional<PropertyCellRef> JSGlobalObjectRef::GetPropertyCell( 22331cb0ef41Sopenharmony_ci NameRef const& name) const { 22341cb0ef41Sopenharmony_ci base::Optional<PropertyCell> maybe_cell = 22351cb0ef41Sopenharmony_ci ConcurrentLookupIterator::TryGetPropertyCell( 22361cb0ef41Sopenharmony_ci broker()->isolate(), broker()->local_isolate_or_isolate(), 22371cb0ef41Sopenharmony_ci broker()->target_native_context().global_object().object(), 22381cb0ef41Sopenharmony_ci name.object()); 22391cb0ef41Sopenharmony_ci if (!maybe_cell.has_value()) return {}; 22401cb0ef41Sopenharmony_ci return TryMakeRef(broker(), *maybe_cell); 22411cb0ef41Sopenharmony_ci} 22421cb0ef41Sopenharmony_ci 22431cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& os, const ObjectRef& ref) { 22441cb0ef41Sopenharmony_ci if (!FLAG_concurrent_recompilation) { 22451cb0ef41Sopenharmony_ci // We cannot be in a background thread so it's safe to read the heap. 22461cb0ef41Sopenharmony_ci AllowHandleDereference allow_handle_dereference; 22471cb0ef41Sopenharmony_ci return os << ref.data() << " {" << ref.object() << "}"; 22481cb0ef41Sopenharmony_ci } else if (ref.data_->should_access_heap()) { 22491cb0ef41Sopenharmony_ci return os << ref.data() << " {" << ref.object() << "}"; 22501cb0ef41Sopenharmony_ci } else { 22511cb0ef41Sopenharmony_ci return os << ref.data(); 22521cb0ef41Sopenharmony_ci } 22531cb0ef41Sopenharmony_ci} 22541cb0ef41Sopenharmony_ci 22551cb0ef41Sopenharmony_ciunsigned CodeRef::GetInlinedBytecodeSize() const { 22561cb0ef41Sopenharmony_ci unsigned value = object()->inlined_bytecode_size(); 22571cb0ef41Sopenharmony_ci if (value > 0) { 22581cb0ef41Sopenharmony_ci // Don't report inlined bytecode size if the code object was already 22591cb0ef41Sopenharmony_ci // deoptimized. 22601cb0ef41Sopenharmony_ci value = object()->marked_for_deoptimization() ? 0 : value; 22611cb0ef41Sopenharmony_ci } 22621cb0ef41Sopenharmony_ci return value; 22631cb0ef41Sopenharmony_ci} 22641cb0ef41Sopenharmony_ci 22651cb0ef41Sopenharmony_ci#undef BIMODAL_ACCESSOR 22661cb0ef41Sopenharmony_ci#undef BIMODAL_ACCESSOR_B 22671cb0ef41Sopenharmony_ci#undef BIMODAL_ACCESSOR_C 22681cb0ef41Sopenharmony_ci#undef HEAP_ACCESSOR_B 22691cb0ef41Sopenharmony_ci#undef HEAP_ACCESSOR_C 22701cb0ef41Sopenharmony_ci#undef IF_ACCESS_FROM_HEAP 22711cb0ef41Sopenharmony_ci#undef IF_ACCESS_FROM_HEAP_C 22721cb0ef41Sopenharmony_ci#undef TRACE 22731cb0ef41Sopenharmony_ci#undef TRACE_MISSING 22741cb0ef41Sopenharmony_ci 22751cb0ef41Sopenharmony_ci} // namespace compiler 22761cb0ef41Sopenharmony_ci} // namespace internal 22771cb0ef41Sopenharmony_ci} // namespace v8 2278