heap-refs.h 36.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_HEAP_REFS_H_
#define V8_COMPILER_HEAP_REFS_H_

#include "src/base/optional.h"
#include "src/ic/call-optimization.h"
#include "src/objects/elements-kind.h"
#include "src/objects/feedback-vector.h"
#include "src/objects/instance-type.h"
13
#include "src/utils/boxed-float.h"
14 15

namespace v8 {
16

17 18
class CFunctionInfo;

19 20 21 22 23 24 25 26 27 28 29 30 31 32
namespace internal {

class BytecodeArray;
class CallHandlerInfo;
class FixedDoubleArray;
class FunctionTemplateInfo;
class HeapNumber;
class InternalizedString;
class JSBoundFunction;
class JSDataView;
class JSGlobalProxy;
class JSTypedArray;
class NativeContext;
class ScriptContextTable;
33 34 35 36 37 38 39
template <typename>
class Signature;

namespace wasm {
class ValueType;
struct WasmModule;
}  // namespace wasm
40 41

namespace compiler {
42

43 44 45
class CompilationDependencies;
struct FeedbackSource;
class JSHeapBroker;
46
class ObjectData;
47 48
class PerIsolateCompilerCache;
class PropertyAccessInfo;
49

50 51
// Whether we are loading a property or storing to a property.
// For a store during literal creation, do not walk up the prototype chain.
52 53 54 55 56
// For a define operation, we behave similarly to kStoreInLiteral, but with
// distinct semantics for private class fields (in which private field
// accesses must throw when storing a field which does not exist, or
// adding/defining a field which already exists).
enum class AccessMode { kLoad, kStore, kStoreInLiteral, kHas, kDefine };
57

58 59 60 61
inline bool IsAnyStore(AccessMode mode) {
  return mode == AccessMode::kStore || mode == AccessMode::kStoreInLiteral;
}

62 63 64 65 66 67 68
// Clarifies in function signatures that a method may only be called when
// concurrent inlining is disabled.
class NotConcurrentInliningTag final {
 public:
  explicit NotConcurrentInliningTag(JSHeapBroker* broker);
};

69 70 71 72 73 74 75 76 77 78
enum class OddballType : uint8_t {
  kNone,     // Not an Oddball.
  kBoolean,  // True or False.
  kUndefined,
  kNull,
  kHole,
  kUninitialized,
  kOther  // Oddball, but none of the above.
};

79
enum class RefSerializationKind {
80
  // Skips serialization.
81 82 83 84
  kNeverSerialized,
  // Can be serialized on demand from the background thread.
  kBackgroundSerialized,
};
85

86 87
// This list is sorted such that subtypes appear before their supertypes.
// DO NOT VIOLATE THIS PROPERTY!
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
#define HEAP_BROKER_OBJECT_LIST_BASE(BACKGROUND_SERIALIZED, NEVER_SERIALIZED) \
  /* Subtypes of JSObject */                                                  \
  BACKGROUND_SERIALIZED(JSArray)                                              \
  BACKGROUND_SERIALIZED(JSBoundFunction)                                      \
  BACKGROUND_SERIALIZED(JSDataView)                                           \
  BACKGROUND_SERIALIZED(JSFunction)                                           \
  BACKGROUND_SERIALIZED(JSGlobalObject)                                       \
  BACKGROUND_SERIALIZED(JSGlobalProxy)                                        \
  BACKGROUND_SERIALIZED(JSTypedArray)                                         \
  /* Subtypes of Context */                                                   \
  NEVER_SERIALIZED(NativeContext)                                             \
  /* Subtypes of FixedArray */                                                \
  NEVER_SERIALIZED(ObjectBoilerplateDescription)                              \
  BACKGROUND_SERIALIZED(ScriptContextTable)                                   \
  /* Subtypes of String */                                                    \
  NEVER_SERIALIZED(InternalizedString)                                        \
  /* Subtypes of FixedArrayBase */                                            \
  NEVER_SERIALIZED(BytecodeArray)                                             \
  BACKGROUND_SERIALIZED(FixedArray)                                           \
  NEVER_SERIALIZED(FixedDoubleArray)                                          \
  /* Subtypes of Name */                                                      \
  NEVER_SERIALIZED(String)                                                    \
  NEVER_SERIALIZED(Symbol)                                                    \
  /* Subtypes of JSReceiver */                                                \
  BACKGROUND_SERIALIZED(JSObject)                                             \
  /* Subtypes of HeapObject */                                                \
  NEVER_SERIALIZED(AccessorInfo)                                              \
  NEVER_SERIALIZED(AllocationSite)                                            \
  NEVER_SERIALIZED(ArrayBoilerplateDescription)                               \
  BACKGROUND_SERIALIZED(BigInt)                                               \
  NEVER_SERIALIZED(CallHandlerInfo)                                           \
  NEVER_SERIALIZED(Cell)                                                      \
  NEVER_SERIALIZED(Code)                                                      \
  NEVER_SERIALIZED(CodeDataContainer)                                         \
  NEVER_SERIALIZED(Context)                                                   \
  NEVER_SERIALIZED(DescriptorArray)                                           \
  NEVER_SERIALIZED(FeedbackCell)                                              \
  NEVER_SERIALIZED(FeedbackVector)                                            \
  BACKGROUND_SERIALIZED(FixedArrayBase)                                       \
  NEVER_SERIALIZED(FunctionTemplateInfo)                                      \
  NEVER_SERIALIZED(HeapNumber)                                                \
  BACKGROUND_SERIALIZED(JSReceiver)                                           \
  BACKGROUND_SERIALIZED(Map)                                                  \
  NEVER_SERIALIZED(Name)                                                      \
  BACKGROUND_SERIALIZED(PropertyCell)                                         \
  NEVER_SERIALIZED(RegExpBoilerplateDescription)                              \
  NEVER_SERIALIZED(ScopeInfo)                                                 \
  NEVER_SERIALIZED(SharedFunctionInfo)                                        \
  NEVER_SERIALIZED(SourceTextModule)                                          \
  NEVER_SERIALIZED(TemplateObjectDescription)                                 \
  /* Subtypes of Object */                                                    \
  BACKGROUND_SERIALIZED(HeapObject)

#define HEAP_BROKER_OBJECT_LIST(V) HEAP_BROKER_OBJECT_LIST_BASE(V, V)
#define IGNORE_CASE(...)
#define HEAP_BROKER_BACKGROUND_SERIALIZED_OBJECT_LIST(V) \
  HEAP_BROKER_OBJECT_LIST_BASE(V, IGNORE_CASE)

#define FORWARD_DECL(Name) class Name##Ref;
147
HEAP_BROKER_OBJECT_LIST(FORWARD_DECL)
148 149
#undef FORWARD_DECL

150 151
class ObjectRef;

152 153 154
template <class T>
struct ref_traits;

155 156 157 158 159 160 161 162 163 164 165
#define FORWARD_DECL(Name) class Name##Data;
HEAP_BROKER_BACKGROUND_SERIALIZED_OBJECT_LIST(FORWARD_DECL)
#undef FORWARD_DECL

#define BACKGROUND_SERIALIZED_REF_TRAITS(Name)                     \
  template <>                                                      \
  struct ref_traits<Name> {                                        \
    using ref_type = Name##Ref;                                    \
    using data_type = Name##Data;                                  \
    static constexpr RefSerializationKind ref_serialization_kind = \
        RefSerializationKind::kBackgroundSerialized;               \
166
  };
167 168 169 170 171 172 173 174 175 176 177 178 179 180

#define NEVER_SERIALIZED_REF_TRAITS(Name)                          \
  template <>                                                      \
  struct ref_traits<Name> {                                        \
    using ref_type = Name##Ref;                                    \
    using data_type = ObjectData;                                  \
    static constexpr RefSerializationKind ref_serialization_kind = \
        RefSerializationKind::kNeverSerialized;                    \
  };

HEAP_BROKER_OBJECT_LIST_BASE(BACKGROUND_SERIALIZED_REF_TRAITS,
                             NEVER_SERIALIZED_REF_TRAITS)
#undef NEVER_SERIALIZED_REF_TRAITS
#undef BACKGROUND_SERIALIZED_REF_TRAITS
181

182 183 184 185 186 187 188 189 190 191
template <>
struct ref_traits<Object> {
  using ref_type = ObjectRef;
  // Note: While a bit awkward, this artificial ref serialization kind value is
  // okay: smis are never-serialized, and we never create raw non-smi
  // ObjectRefs (they would at least be HeapObjectRefs instead).
  static constexpr RefSerializationKind ref_serialization_kind =
      RefSerializationKind::kNeverSerialized;
};

192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
// A ref without the broker_ field, used when storage size is important.
template <class T>
class TinyRef {
 private:
  using RefType = typename ref_traits<T>::ref_type;

 public:
  explicit TinyRef(const RefType& ref) : TinyRef(ref.data_) {}
  RefType AsRef(JSHeapBroker* broker) const;
  static base::Optional<RefType> AsOptionalRef(JSHeapBroker* broker,
                                               base::Optional<TinyRef<T>> ref) {
    if (!ref.has_value()) return {};
    return ref->AsRef(broker);
  }
  Handle<T> object() const;

 private:
  explicit TinyRef(ObjectData* data) : data_(data) { DCHECK_NOT_NULL(data); }
  ObjectData* const data_;
};

#define V(Name) using Name##TinyRef = TinyRef<Name>;
HEAP_BROKER_OBJECT_LIST(V)
#undef V

217 218 219 220 221 222 223 224
#ifdef V8_EXTERNAL_CODE_SPACE
using CodeTRef = CodeDataContainerRef;
using CodeTTinyRef = CodeDataContainerTinyRef;
#else
using CodeTRef = CodeRef;
using CodeTTinyRef = CodeTinyRef;
#endif

225 226
class V8_EXPORT_PRIVATE ObjectRef {
 public:
227
  ObjectRef(JSHeapBroker* broker, ObjectData* data, bool check_type = true)
228 229 230
      : data_(data), broker_(broker) {
    CHECK_NOT_NULL(data_);
  }
231

232 233 234 235 236 237 238
  Handle<Object> object() const;

  bool equals(const ObjectRef& other) const;

  bool IsSmi() const;
  int AsSmi() const;

239
#define HEAP_IS_METHOD_DECL(Name) bool Is##Name() const;
240
  HEAP_BROKER_OBJECT_LIST(HEAP_IS_METHOD_DECL)
241 242
#undef HEAP_IS_METHOD_DECL

243
#define HEAP_AS_METHOD_DECL(Name) Name##Ref As##Name() const;
244
  HEAP_BROKER_OBJECT_LIST(HEAP_AS_METHOD_DECL)
245 246
#undef HEAP_AS_METHOD_DECL

247
  bool IsNull() const;
248
  bool IsNullOrUndefined() const;
249
  bool IsTheHole() const;
250

251
  base::Optional<bool> TryGetBooleanValue() const;
252 253
  Maybe<double> OddballToNumber() const;

254 255
  bool should_access_heap() const;

256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276
  Isolate* isolate() const;

  struct Hash {
    size_t operator()(const ObjectRef& ref) const {
      return base::hash_combine(ref.object().address());
    }
  };
  struct Equal {
    bool operator()(const ObjectRef& lhs, const ObjectRef& rhs) const {
      return lhs.equals(rhs);
    }
  };

 protected:
  JSHeapBroker* broker() const;
  ObjectData* data() const;
  ObjectData* data_;  // Should be used only by object() getters.

 private:
  friend class FunctionTemplateInfoRef;
  friend class JSArrayData;
277
  friend class JSFunctionData;
278 279
  friend class JSGlobalObjectData;
  friend class JSGlobalObjectRef;
280
  friend class JSHeapBroker;
281 282
  friend class JSObjectData;
  friend class StringData;
283 284
  template <class T>
  friend class TinyRef;
285 286 287 288 289 290

  friend std::ostream& operator<<(std::ostream& os, const ObjectRef& ref);

  JSHeapBroker* broker_;
};

291 292 293 294
template <class T>
using ZoneRefUnorderedSet =
    ZoneUnorderedSet<T, ObjectRef::Hash, ObjectRef::Equal>;

295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
// Temporary class that carries information from a Map. We'd like to remove
// this class and use MapRef instead, but we can't as long as we support the
// kDisabled broker mode. That's because obtaining the MapRef via
// HeapObjectRef::map() requires a HandleScope when the broker is disabled.
// During OptimizeGraph we generally don't have a HandleScope, however. There
// are two places where we therefore use GetHeapObjectType() instead. Both that
// function and this class should eventually be removed.
class HeapObjectType {
 public:
  enum Flag : uint8_t { kUndetectable = 1 << 0, kCallable = 1 << 1 };

  using Flags = base::Flags<Flag>;

  HeapObjectType(InstanceType instance_type, Flags flags,
                 OddballType oddball_type)
      : instance_type_(instance_type),
        oddball_type_(oddball_type),
        flags_(flags) {
    DCHECK_EQ(instance_type == ODDBALL_TYPE,
              oddball_type != OddballType::kNone);
  }

  OddballType oddball_type() const { return oddball_type_; }
  InstanceType instance_type() const { return instance_type_; }
  Flags flags() const { return flags_; }

  bool is_callable() const { return flags_ & kCallable; }
  bool is_undetectable() const { return flags_ & kUndetectable; }

 private:
  InstanceType const instance_type_;
  OddballType const oddball_type_;
  Flags const flags_;
};

330 331
// Constructors are carefully defined such that we do a type check on
// the outermost Ref class in the inheritance chain only.
332 333 334
#define DEFINE_REF_CONSTRUCTOR(Name, Base)                                  \
  Name##Ref(JSHeapBroker* broker, ObjectData* data, bool check_type = true) \
      : Base(broker, data, false) {                                         \
335
    if (check_type) {                                                       \
336
      CHECK(Is##Name());                                                    \
337 338 339
    }                                                                       \
  }

340 341
class HeapObjectRef : public ObjectRef {
 public:
342
  DEFINE_REF_CONSTRUCTOR(HeapObject, ObjectRef)
343

344 345 346 347
  Handle<HeapObject> object() const;

  MapRef map() const;

348 349 350 351
  // Only for use in special situations where we need to read the object's
  // current map (instead of returning the cached map). Use with care.
  base::Optional<MapRef> map_direct_read() const;

352 353 354 355 356 357
  // See the comment on the HeapObjectType class.
  HeapObjectType GetHeapObjectType() const;
};

class PropertyCellRef : public HeapObjectRef {
 public:
358
  DEFINE_REF_CONSTRUCTOR(PropertyCell, HeapObjectRef)
359

360 361
  Handle<PropertyCell> object() const;

362 363 364
  V8_WARN_UNUSED_RESULT bool Cache() const;
  void CacheAsProtector() const {
    bool cached = Cache();
365
    // A protector always holds a Smi value and its cell type never changes, so
366 367
    // Cache can't fail.
    CHECK(cached);
368
  }
369

370
  PropertyDetails property_details() const;
371 372 373
  ObjectRef value() const;
};

374
class JSReceiverRef : public HeapObjectRef {
375
 public:
376
  DEFINE_REF_CONSTRUCTOR(JSReceiver, HeapObjectRef)
377

378 379 380 381 382
  Handle<JSReceiver> object() const;
};

class JSObjectRef : public JSReceiverRef {
 public:
383
  DEFINE_REF_CONSTRUCTOR(JSObject, JSReceiverRef)
384

385 386
  Handle<JSObject> object() const;

387 388
  base::Optional<ObjectRef> raw_properties_or_hash() const;

389 390 391 392
  // Usable only for in-object properties. Only use this if the underlying
  // value can be an uninitialized-sentinel, or if HeapNumber construction must
  // be avoided for some reason. Otherwise, use the higher-level
  // GetOwnFastDataProperty.
393
  base::Optional<ObjectRef> RawInobjectPropertyAt(FieldIndex index) const;
394

395
  // Return the element at key {index} if {index} is known to be an own data
396 397 398
  // property of the object that is non-writable and non-configurable. If
  // {dependencies} is non-null, a dependency will be taken to protect
  // against inconsistency due to weak memory concurrency.
399
  base::Optional<ObjectRef> GetOwnConstantElement(
400
      const FixedArrayBaseRef& elements_ref, uint32_t index,
401
      CompilationDependencies* dependencies) const;
402 403 404 405 406 407
  // The direct-read implementation of the above, extracted into a helper since
  // it's also called from compilation-dependency validation. This helper is
  // guaranteed to not create new Ref instances.
  base::Optional<Object> GetOwnConstantElementFromHeap(
      FixedArrayBase elements, ElementsKind elements_kind,
      uint32_t index) const;
408

409 410
  // Return the value of the property identified by the field {index}
  // if {index} is known to be an own data property of the object.
411 412 413
  // If {dependencies} is non-null, and a property was successfully read,
  // then the function will take a dependency to check the value of the
  // property at code finalization time.
414
  base::Optional<ObjectRef> GetOwnFastDataProperty(
415
      Representation field_representation, FieldIndex index,
416
      CompilationDependencies* dependencies) const;
417 418 419

  // Return the value of the dictionary property at {index} in the dictionary
  // if {index} is known to be an own data property of the object.
420
  base::Optional<ObjectRef> GetOwnDictionaryProperty(
421
      InternalIndex index, CompilationDependencies* dependencies) const;
422

423 424 425 426
  // When concurrent inlining is enabled, reads the elements through a direct
  // relaxed read. This is to ease the transition to unserialized (or
  // background-serialized) elements.
  base::Optional<FixedArrayBaseRef> elements(RelaxedLoadTag) const;
427
  void SerializeElements(NotConcurrentInliningTag tag);
428
  bool IsElementsTenured(const FixedArrayBaseRef& elements);
429

430
  void SerializeObjectCreateMap(NotConcurrentInliningTag tag);
431
  base::Optional<MapRef> GetObjectCreateMap() const;
432

433
  void SerializeAsBoilerplateRecursive(NotConcurrentInliningTag tag);
434 435 436 437
};

class JSDataViewRef : public JSObjectRef {
 public:
438
  DEFINE_REF_CONSTRUCTOR(JSDataView, JSObjectRef)
439

440 441 442 443 444 445 446
  Handle<JSDataView> object() const;

  size_t byte_length() const;
};

class JSBoundFunctionRef : public JSObjectRef {
 public:
447
  DEFINE_REF_CONSTRUCTOR(JSBoundFunction, JSObjectRef)
448

449 450
  Handle<JSBoundFunction> object() const;

451 452
  JSReceiverRef bound_target_function() const;
  ObjectRef bound_this() const;
453 454 455 456 457
  FixedArrayRef bound_arguments() const;
};

class V8_EXPORT_PRIVATE JSFunctionRef : public JSObjectRef {
 public:
458
  DEFINE_REF_CONSTRUCTOR(JSFunction, JSObjectRef)
459

460 461
  Handle<JSFunction> object() const;

462 463 464 465 466
  // Returns true, iff the serialized JSFunctionData contents are consistent
  // with the state of the underlying JSFunction object. Must be called from
  // the main thread.
  bool IsConsistentWithHeapState() const;

467 468 469
  ContextRef context() const;
  NativeContextRef native_context() const;
  SharedFunctionInfoRef shared() const;
470
  CodeRef code() const;
471

472 473 474 475 476 477 478 479 480 481
  bool has_initial_map(CompilationDependencies* dependencies) const;
  bool PrototypeRequiresRuntimeLookup(
      CompilationDependencies* dependencies) const;
  bool has_instance_prototype(CompilationDependencies* dependencies) const;
  ObjectRef instance_prototype(CompilationDependencies* dependencies) const;
  MapRef initial_map(CompilationDependencies* dependencies) const;
  int InitialMapInstanceSizeWithMinSlack(
      CompilationDependencies* dependencies) const;
  FeedbackCellRef raw_feedback_cell(
      CompilationDependencies* dependencies) const;
482 483
  base::Optional<FeedbackVectorRef> feedback_vector(
      CompilationDependencies* dependencies) const;
484 485
};

486
class RegExpBoilerplateDescriptionRef : public HeapObjectRef {
487
 public:
488
  DEFINE_REF_CONSTRUCTOR(RegExpBoilerplateDescription, HeapObjectRef)
489

490
  Handle<RegExpBoilerplateDescription> object() const;
491

492
  void Serialize(NotConcurrentInliningTag tag);
493

494 495 496
  FixedArrayRef data() const;
  StringRef source() const;
  int flags() const;
497 498
};

499 500 501 502 503
// HeapNumberRef is only created for immutable HeapNumbers. Mutable
// HeapNumbers (those owned by in-object or backing store fields with
// representation type Double are not exposed to the compiler through
// HeapNumberRef. Instead, we read their value, and protect that read
// with a field-constness Dependency.
504 505
class HeapNumberRef : public HeapObjectRef {
 public:
506
  DEFINE_REF_CONSTRUCTOR(HeapNumber, HeapObjectRef)
507

508 509 510
  Handle<HeapNumber> object() const;

  double value() const;
511
  uint64_t value_as_bits() const;
512 513 514 515
};

class ContextRef : public HeapObjectRef {
 public:
516
  DEFINE_REF_CONSTRUCTOR(Context, HeapObjectRef)
517

518 519
  Handle<Context> object() const;

520
  // {previous} decrements {depth} by 1 for each previous link successfully
521
  // followed. If {depth} != 0 on function return, then it only got partway to
522 523
  // the desired depth.
  ContextRef previous(size_t* depth) const;
524 525

  // Only returns a value if the index is valid for this ContextRef.
526
  base::Optional<ObjectRef> get(int index) const;
527 528
};

529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
#define BROKER_NATIVE_CONTEXT_FIELDS(V)          \
  V(JSFunction, array_function)                  \
  V(JSFunction, bigint_function)                 \
  V(JSFunction, boolean_function)                \
  V(JSFunction, function_prototype_apply)        \
  V(JSFunction, number_function)                 \
  V(JSFunction, object_function)                 \
  V(JSFunction, promise_function)                \
  V(JSFunction, promise_then)                    \
  V(JSFunction, regexp_exec_function)            \
  V(JSFunction, regexp_function)                 \
  V(JSFunction, string_function)                 \
  V(JSFunction, symbol_function)                 \
  V(JSGlobalObject, global_object)               \
  V(JSGlobalProxy, global_proxy_object)          \
544
  V(JSObject, initial_array_prototype)           \
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571
  V(JSObject, promise_prototype)                 \
  V(Map, async_function_object_map)              \
  V(Map, block_context_map)                      \
  V(Map, bound_function_with_constructor_map)    \
  V(Map, bound_function_without_constructor_map) \
  V(Map, catch_context_map)                      \
  V(Map, eval_context_map)                       \
  V(Map, fast_aliased_arguments_map)             \
  V(Map, function_context_map)                   \
  V(Map, initial_array_iterator_map)             \
  V(Map, initial_string_iterator_map)            \
  V(Map, iterator_result_map)                    \
  V(Map, js_array_holey_double_elements_map)     \
  V(Map, js_array_holey_elements_map)            \
  V(Map, js_array_holey_smi_elements_map)        \
  V(Map, js_array_packed_double_elements_map)    \
  V(Map, js_array_packed_elements_map)           \
  V(Map, js_array_packed_smi_elements_map)       \
  V(Map, map_key_iterator_map)                   \
  V(Map, map_key_value_iterator_map)             \
  V(Map, map_value_iterator_map)                 \
  V(Map, set_key_value_iterator_map)             \
  V(Map, set_value_iterator_map)                 \
  V(Map, sloppy_arguments_map)                   \
  V(Map, slow_object_with_null_prototype_map)    \
  V(Map, strict_arguments_map)                   \
  V(Map, with_context_map)                       \
572
  V(ScriptContextTable, script_context_table)
573 574 575

class NativeContextRef : public ContextRef {
 public:
576
  DEFINE_REF_CONSTRUCTOR(NativeContext, ContextRef)
577

578 579
  Handle<NativeContext> object() const;

580
  void Serialize(NotConcurrentInliningTag tag);
581 582 583 584 585 586 587 588 589

#define DECL_ACCESSOR(type, name) type##Ref name() const;
  BROKER_NATIVE_CONTEXT_FIELDS(DECL_ACCESSOR)
#undef DECL_ACCESSOR

  ScopeInfoRef scope_info() const;
  MapRef GetFunctionMapFromIndex(int index) const;
  MapRef GetInitialJSArrayMap(ElementsKind kind) const;
  base::Optional<JSFunctionRef> GetConstructorFunction(const MapRef& map) const;
590
  bool GlobalIsDetached() const;
591 592 593 594
};

class NameRef : public HeapObjectRef {
 public:
595
  DEFINE_REF_CONSTRUCTOR(Name, HeapObjectRef)
596

597 598 599 600 601 602 603
  Handle<Name> object() const;

  bool IsUniqueName() const;
};

class DescriptorArrayRef : public HeapObjectRef {
 public:
604
  DEFINE_REF_CONSTRUCTOR(DescriptorArray, HeapObjectRef)
605

606
  Handle<DescriptorArray> object() const;
607 608

  PropertyDetails GetPropertyDetails(InternalIndex descriptor_index) const;
609
  NameRef GetPropertyKey(InternalIndex descriptor_index) const;
610 611
  base::Optional<ObjectRef> GetStrongValue(
      InternalIndex descriptor_index) const;
612 613 614 615
};

class FeedbackCellRef : public HeapObjectRef {
 public:
616
  DEFINE_REF_CONSTRUCTOR(FeedbackCell, HeapObjectRef)
617

618
  Handle<FeedbackCell> object() const;
619 620 621 622 623

  ObjectRef value() const;

  // Convenience wrappers around {value()}:
  base::Optional<FeedbackVectorRef> feedback_vector() const;
624
  base::Optional<SharedFunctionInfoRef> shared_function_info() const;
625 626 627 628
};

class FeedbackVectorRef : public HeapObjectRef {
 public:
629
  DEFINE_REF_CONSTRUCTOR(FeedbackVector, HeapObjectRef)
630

631 632
  Handle<FeedbackVector> object() const;

633
  SharedFunctionInfoRef shared_function_info() const;
634

635
  FeedbackCellRef GetClosureFeedbackCell(int index) const;
636 637 638 639
};

class CallHandlerInfoRef : public HeapObjectRef {
 public:
640
  DEFINE_REF_CONSTRUCTOR(CallHandlerInfo, HeapObjectRef)
641

642 643 644 645 646 647
  Handle<CallHandlerInfo> object() const;

  Address callback() const;
  ObjectRef data() const;
};

648 649
class AccessorInfoRef : public HeapObjectRef {
 public:
650
  DEFINE_REF_CONSTRUCTOR(AccessorInfo, HeapObjectRef)
651

652 653 654
  Handle<AccessorInfo> object() const;
};

655 656
class AllocationSiteRef : public HeapObjectRef {
 public:
657
  DEFINE_REF_CONSTRUCTOR(AllocationSite, HeapObjectRef)
658

659 660 661 662 663 664
  Handle<AllocationSite> object() const;

  bool PointsToLiteral() const;
  AllocationType GetAllocationType() const;
  ObjectRef nested_site() const;

665
  void SerializeRecursive(NotConcurrentInliningTag tag);
666

667 668 669 670 671
  base::Optional<JSObjectRef> boilerplate() const;
  ElementsKind GetElementsKind() const;
  bool CanInlineCall() const;
};

672 673
class BigIntRef : public HeapObjectRef {
 public:
674
  DEFINE_REF_CONSTRUCTOR(BigInt, HeapObjectRef)
675

676 677 678 679 680
  Handle<BigInt> object() const;

  uint64_t AsUint64() const;
};

681 682
class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef {
 public:
683
  DEFINE_REF_CONSTRUCTOR(Map, HeapObjectRef)
684

685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713
  Handle<Map> object() const;

  int instance_size() const;
  InstanceType instance_type() const;
  int GetInObjectProperties() const;
  int GetInObjectPropertiesStartInWords() const;
  int NumberOfOwnDescriptors() const;
  int GetInObjectPropertyOffset(int index) const;
  int constructor_function_index() const;
  int NextFreePropertyIndex() const;
  int UnusedPropertyFields() const;
  ElementsKind elements_kind() const;
  bool is_stable() const;
  bool is_constructor() const;
  bool has_prototype_slot() const;
  bool is_access_check_needed() const;
  bool is_deprecated() const;
  bool CanBeDeprecated() const;
  bool CanTransition() const;
  bool IsInobjectSlackTrackingInProgress() const;
  bool is_dictionary_map() const;
  bool IsFixedCowArrayMap() const;
  bool IsPrimitiveMap() const;
  bool is_undetectable() const;
  bool is_callable() const;
  bool has_indexed_interceptor() const;
  bool is_migration_target() const;
  bool supports_fast_array_iteration() const;
  bool supports_fast_array_resize() const;
714
  bool is_abandoned_prototype_map() const;
715 716 717

  OddballType oddball_type() const;

718 719
  bool CanInlineElementAccess() const;

720 721 722 723
  // Note: Only returns a value if the requested elements kind matches the
  // current kind, or if the current map is an unmodified JSArray initial map.
  base::Optional<MapRef> AsElementsKind(ElementsKind kind) const;

724 725 726 727
#define DEF_TESTER(Type, ...) bool Is##Type##Map() const;
  INSTANCE_TYPE_CHECKERS(DEF_TESTER)
#undef DEF_TESTER

728
  void SerializeBackPointer(NotConcurrentInliningTag tag);
729 730
  HeapObjectRef GetBackPointer() const;

731
  void SerializePrototype(NotConcurrentInliningTag tag);
732 733 734
  // TODO(neis): We should be able to remove TrySerializePrototype once
  // concurrent-inlining is always on. Then we can also change the return type
  // of prototype() back to HeapObjectRef.
735
  bool TrySerializePrototype(NotConcurrentInliningTag tag);
736
  base::Optional<HeapObjectRef> prototype() const;
737

738
  void SerializeForElementStore(NotConcurrentInliningTag tag);
739 740 741 742
  bool HasOnlyStablePrototypesWithFastElements(
      ZoneVector<MapRef>* prototype_maps);

  // Concerning the underlying instance_descriptors:
743
  DescriptorArrayRef instance_descriptors() const;
744 745 746 747
  MapRef FindFieldOwner(InternalIndex descriptor_index) const;
  PropertyDetails GetPropertyDetails(InternalIndex descriptor_index) const;
  NameRef GetPropertyKey(InternalIndex descriptor_index) const;
  FieldIndex GetFieldIndexFor(InternalIndex descriptor_index) const;
748 749
  base::Optional<ObjectRef> GetStrongValue(
      InternalIndex descriptor_number) const;
750

751
  MapRef FindRootMap() const;
752 753 754 755 756 757 758 759 760 761 762 763 764 765
  ObjectRef GetConstructor() const;
};

struct HolderLookupResult {
  HolderLookupResult(CallOptimization::HolderLookup lookup_ =
                         CallOptimization::kHolderNotFound,
                     base::Optional<JSObjectRef> holder_ = base::nullopt)
      : lookup(lookup_), holder(holder_) {}
  CallOptimization::HolderLookup lookup;
  base::Optional<JSObjectRef> holder;
};

class FunctionTemplateInfoRef : public HeapObjectRef {
 public:
766
  DEFINE_REF_CONSTRUCTOR(FunctionTemplateInfo, HeapObjectRef)
767

768 769 770 771 772
  Handle<FunctionTemplateInfo> object() const;

  bool is_signature_undefined() const;
  bool accept_any_receiver() const;
  base::Optional<CallHandlerInfoRef> call_code() const;
773 774
  ZoneVector<Address> c_functions() const;
  ZoneVector<const CFunctionInfo*> c_signatures() const;
775
  HolderLookupResult LookupHolderOfExpectedType(MapRef receiver_map);
776 777 778 779
};

class FixedArrayBaseRef : public HeapObjectRef {
 public:
780
  DEFINE_REF_CONSTRUCTOR(FixedArrayBase, HeapObjectRef)
781

782 783 784 785 786
  Handle<FixedArrayBase> object() const;

  int length() const;
};

787 788 789 790 791 792 793 794
class ArrayBoilerplateDescriptionRef : public HeapObjectRef {
 public:
  using HeapObjectRef::HeapObjectRef;
  Handle<ArrayBoilerplateDescription> object() const;

  int constants_elements_length() const;
};

795 796
class FixedArrayRef : public FixedArrayBaseRef {
 public:
797
  DEFINE_REF_CONSTRUCTOR(FixedArray, FixedArrayBaseRef)
798

799 800
  Handle<FixedArray> object() const;

801
  base::Optional<ObjectRef> TryGet(int i) const;
802 803 804 805
};

class FixedDoubleArrayRef : public FixedArrayBaseRef {
 public:
806
  DEFINE_REF_CONSTRUCTOR(FixedDoubleArray, FixedArrayBaseRef)
807

808 809
  Handle<FixedDoubleArray> object() const;

810 811 812 813
  // Due to 64-bit unaligned reads, only usable for
  // immutable-after-initialization FixedDoubleArrays protected by
  // acquire-release semantics (such as boilerplate elements).
  Float64 GetFromImmutableFixedDoubleArray(int i) const;
814 815 816 817
};

class BytecodeArrayRef : public FixedArrayBaseRef {
 public:
818
  DEFINE_REF_CONSTRUCTOR(BytecodeArray, FixedArrayBaseRef)
819

820 821
  Handle<BytecodeArray> object() const;

822 823
  // NOTE: Concurrent reads of the actual bytecodes as well as the constant pool
  // (both immutable) do not go through BytecodeArrayRef but are performed
824
  // directly through the handle by BytecodeArrayIterator.
825

826 827 828 829
  int register_count() const;
  int parameter_count() const;
  interpreter::Register incoming_new_target_or_generator_register() const;

830
  Handle<ByteArray> SourcePositionTable() const;
831

832 833 834
  // Exception handler table.
  Address handler_table_address() const;
  int handler_table_size() const;
835 836
};

837 838
class ScriptContextTableRef : public FixedArrayRef {
 public:
839
  DEFINE_REF_CONSTRUCTOR(ScriptContextTable, FixedArrayRef)
840 841 842 843 844 845

  Handle<ScriptContextTable> object() const;
};

class ObjectBoilerplateDescriptionRef : public FixedArrayRef {
 public:
846
  DEFINE_REF_CONSTRUCTOR(ObjectBoilerplateDescription, FixedArrayRef)
847 848 849 850 851 852

  Handle<ObjectBoilerplateDescription> object() const;

  int size() const;
};

853 854
class JSArrayRef : public JSObjectRef {
 public:
855
  DEFINE_REF_CONSTRUCTOR(JSArray, JSObjectRef)
856

857 858
  Handle<JSArray> object() const;

859 860 861 862
  // The `length` property of boilerplate JSArray objects. Boilerplates are
  // immutable after initialization. Must not be used for non-boilerplate
  // JSArrays.
  ObjectRef GetBoilerplateLength() const;
863 864 865

  // Return the element at key {index} if the array has a copy-on-write elements
  // storage and {index} is known to be an own data property.
866 867
  // Note the value returned by this function is only valid if we ensure at
  // runtime that the backing store has not changed.
868 869
  base::Optional<ObjectRef> GetOwnCowElement(FixedArrayBaseRef elements_ref,
                                             uint32_t index) const;
870 871 872

  // The `JSArray::length` property; not safe to use in general, but can be
  // used in some special cases that guarantee a valid `length` value despite
873 874 875
  // concurrent reads. The result needs to be optional in case the
  // return value was created too recently to pass the gc predicate.
  base::Optional<ObjectRef> length_unsafe() const;
876 877 878 879
};

class ScopeInfoRef : public HeapObjectRef {
 public:
880
  DEFINE_REF_CONSTRUCTOR(ScopeInfo, HeapObjectRef)
881

882 883 884
  Handle<ScopeInfo> object() const;

  int ContextLength() const;
885
  bool HasOuterScopeInfo() const;
886
  bool HasContextExtensionSlot() const;
887 888

  ScopeInfoRef OuterScopeInfo() const;
889 890
};

891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907
#define BROKER_SFI_FIELDS(V)                               \
  V(int, internal_formal_parameter_count_without_receiver) \
  V(bool, IsDontAdaptArguments)                            \
  V(bool, has_simple_parameters)                           \
  V(bool, has_duplicate_parameters)                        \
  V(int, function_map_index)                               \
  V(FunctionKind, kind)                                    \
  V(LanguageMode, language_mode)                           \
  V(bool, native)                                          \
  V(bool, HasBreakInfo)                                    \
  V(bool, HasBuiltinId)                                    \
  V(bool, construct_as_builtin)                            \
  V(bool, HasBytecodeArray)                                \
  V(int, StartPosition)                                    \
  V(bool, is_compiled)                                     \
  V(bool, IsUserJavaScript)                                \
  IF_WASM(V, const wasm::WasmModule*, wasm_module)         \
908
  IF_WASM(V, const wasm::FunctionSig*, wasm_function_signature)
909 910 911

class V8_EXPORT_PRIVATE SharedFunctionInfoRef : public HeapObjectRef {
 public:
912
  DEFINE_REF_CONSTRUCTOR(SharedFunctionInfo, HeapObjectRef)
913

914 915
  Handle<SharedFunctionInfo> object() const;

916
  Builtin builtin_id() const;
917
  int context_header_size() const;
918
  int context_parameters_start() const;
919
  BytecodeArrayRef GetBytecodeArray() const;
920
  SharedFunctionInfo::Inlineability GetInlineability() const;
921 922
  base::Optional<FunctionTemplateInfoRef> function_template_info() const;
  ScopeInfoRef scope_info() const;
923 924 925 926 927

#define DECL_ACCESSOR(type, name) type name() const;
  BROKER_SFI_FIELDS(DECL_ACCESSOR)
#undef DECL_ACCESSOR

928 929 930
  bool IsInlineable() const {
    return GetInlineability() == SharedFunctionInfo::kIsInlineable;
  }
931 932 933 934
};

class StringRef : public NameRef {
 public:
935
  DEFINE_REF_CONSTRUCTOR(String, NameRef)
936

937 938
  Handle<String> object() const;

939 940
  // With concurrent inlining on, we return base::nullopt due to not being able
  // to use LookupIterator in a thread-safe way.
941
  base::Optional<ObjectRef> GetCharAsStringOrUndefined(uint32_t index) const;
942

943 944
  // When concurrently accessing non-read-only non-supported strings, we return
  // base::nullopt for these methods.
945
  base::Optional<Handle<String>> ObjectIfContentAccessible();
946
  base::Optional<int> length() const;
947
  base::Optional<uint16_t> GetFirstChar();
948
  base::Optional<double> ToNumber();
949

950 951
  bool IsSeqString() const;
  bool IsExternalString() const;
952 953 954 955 956 957

 private:
  // With concurrent inlining on, we currently support reading directly
  // internalized strings, and thin strings (which are pointers to internalized
  // strings).
  bool SupportedStringKind() const;
958 959 960 961
};

class SymbolRef : public NameRef {
 public:
962
  DEFINE_REF_CONSTRUCTOR(Symbol, NameRef)
963

964 965 966 967 968
  Handle<Symbol> object() const;
};

class JSTypedArrayRef : public JSObjectRef {
 public:
969
  DEFINE_REF_CONSTRUCTOR(JSTypedArray, JSObjectRef)
970

971 972 973 974
  Handle<JSTypedArray> object() const;

  bool is_on_heap() const;
  size_t length() const;
975
  void* data_ptr() const;
976 977 978 979 980
  HeapObjectRef buffer() const;
};

class SourceTextModuleRef : public HeapObjectRef {
 public:
981
  DEFINE_REF_CONSTRUCTOR(SourceTextModule, HeapObjectRef)
982

983 984
  Handle<SourceTextModule> object() const;

985
  base::Optional<CellRef> GetCell(int cell_index) const;
986
  base::Optional<ObjectRef> import_meta() const;
987 988
};

989 990
class TemplateObjectDescriptionRef : public HeapObjectRef {
 public:
991
  DEFINE_REF_CONSTRUCTOR(TemplateObjectDescription, HeapObjectRef)
992 993 994 995

  Handle<TemplateObjectDescription> object() const;
};

996 997
class CellRef : public HeapObjectRef {
 public:
998
  DEFINE_REF_CONSTRUCTOR(Cell, HeapObjectRef)
999

1000 1001 1002
  Handle<Cell> object() const;
};

1003 1004
class JSGlobalObjectRef : public JSObjectRef {
 public:
1005
  DEFINE_REF_CONSTRUCTOR(JSGlobalObject, JSObjectRef)
1006 1007

  Handle<JSGlobalObject> object() const;
1008

1009
  bool IsDetachedFrom(JSGlobalProxyRef const& proxy) const;
1010

1011
  // Can be called even when there is no property cell for the given name.
1012
  base::Optional<PropertyCellRef> GetPropertyCell(NameRef const& name) const;
1013 1014
};

1015 1016
class JSGlobalProxyRef : public JSObjectRef {
 public:
1017
  DEFINE_REF_CONSTRUCTOR(JSGlobalProxy, JSObjectRef)
1018 1019 1020 1021

  Handle<JSGlobalProxy> object() const;
};

1022 1023
class CodeRef : public HeapObjectRef {
 public:
1024
  DEFINE_REF_CONSTRUCTOR(Code, HeapObjectRef)
1025

1026
  Handle<Code> object() const;
1027

1028
  unsigned GetInlinedBytecodeSize() const;
1029 1030
};

1031 1032 1033 1034 1035 1036 1037 1038 1039
// CodeDataContainerRef doesn't appear to be used, but it is used via CodeT when
// V8_EXTERNAL_CODE_SPACE is defined.
class CodeDataContainerRef : public HeapObjectRef {
 public:
  DEFINE_REF_CONSTRUCTOR(CodeDataContainer, HeapObjectRef)

  Handle<CodeDataContainer> object() const;
};

1040 1041
class InternalizedStringRef : public StringRef {
 public:
1042
  DEFINE_REF_CONSTRUCTOR(InternalizedString, StringRef)
1043

1044 1045
  Handle<InternalizedString> object() const;
};
1046

1047 1048
#undef DEFINE_REF_CONSTRUCTOR

1049 1050 1051 1052 1053
}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_HEAP_REFS_H_