• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_COMPILER_HEAP_REFS_H_
6 #define V8_COMPILER_HEAP_REFS_H_
7 
8 #include "src/base/optional.h"
9 #include "src/ic/call-optimization.h"
10 #include "src/objects/elements-kind.h"
11 #include "src/objects/feedback-vector.h"
12 #include "src/objects/instance-type.h"
13 #include "src/utils/boxed-float.h"
14 
15 namespace v8 {
16 
17 class CFunctionInfo;
18 
19 namespace internal {
20 
21 class BytecodeArray;
22 class CallHandlerInfo;
23 class FixedDoubleArray;
24 class FunctionTemplateInfo;
25 class HeapNumber;
26 class InternalizedString;
27 class JSBoundFunction;
28 class JSDataView;
29 class JSGlobalProxy;
30 class JSRegExp;
31 class JSTypedArray;
32 class NativeContext;
33 class ScriptContextTable;
34 
35 namespace compiler {
36 
37 // Whether we are loading a property or storing to a property.
38 // For a store during literal creation, do not walk up the prototype chain.
39 enum class AccessMode { kLoad, kStore, kStoreInLiteral, kHas };
40 
41 enum class SerializationPolicy { kAssumeSerialized, kSerializeIfNeeded };
42 
43 enum class OddballType : uint8_t {
44   kNone,     // Not an Oddball.
45   kBoolean,  // True or False.
46   kUndefined,
47   kNull,
48   kHole,
49   kUninitialized,
50   kOther  // Oddball, but none of the above.
51 };
52 
53 // This list is sorted such that subtypes appear before their supertypes.
54 // This list must not contain a type if it doesn't contain all of its subtypes
55 // too. For example, it CANNOT contain FixedArrayBase if it doesn't contain
56 // FixedDoubleArray, BytecodeArray and FixedArray.
57 // DO NOT VIOLATE THESE TWO PROPERTIES!
58 // Classes on this list will skip serialization when
59 // FLAG_turbo_direct_heap_access is on. Otherwise, they might get serialized.
60 #define HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(V) \
61   /* Subtypes of FixedArray */                      \
62   V(ObjectBoilerplateDescription)                   \
63   V(ScopeInfo)                                      \
64   /* Subtypes of Name */                            \
65   V(Symbol)                                         \
66   /* Subtypes of HeapObject */                      \
67   V(AccessorInfo)                                   \
68   V(ArrayBoilerplateDescription)                    \
69   V(CallHandlerInfo)                                \
70   V(Cell)                                           \
71   V(TemplateObjectDescription)
72 
73 // This list is sorted such that subtypes appear before their supertypes.
74 // DO NOT VIOLATE THIS PROPERTY!
75 #define HEAP_BROKER_SERIALIZED_OBJECT_LIST(V) \
76   /* Subtypes of JSObject */                  \
77   V(JSArray)                                  \
78   V(JSBoundFunction)                          \
79   V(JSDataView)                               \
80   V(JSFunction)                               \
81   V(JSGlobalObject)                           \
82   V(JSGlobalProxy)                            \
83   V(JSRegExp)                                 \
84   V(JSTypedArray)                             \
85   /* Subtypes of Context */                   \
86   V(NativeContext)                            \
87   /* Subtypes of FixedArray */                \
88   V(Context)                                  \
89   V(ScriptContextTable)                       \
90   /* Subtypes of FixedArrayBase */            \
91   V(BytecodeArray)                            \
92   V(FixedArray)                               \
93   V(FixedDoubleArray)                         \
94   /* Subtypes of Name */                      \
95   V(InternalizedString)                       \
96   V(String)                                   \
97   /* Subtypes of JSReceiver */                \
98   V(JSObject)                                 \
99   /* Subtypes of HeapObject */                \
100   V(AllocationSite)                           \
101   V(BigInt)                                   \
102   V(Code)                                     \
103   V(DescriptorArray)                          \
104   V(FeedbackCell)                             \
105   V(FeedbackVector)                           \
106   V(FixedArrayBase)                           \
107   V(FunctionTemplateInfo)                     \
108   V(HeapNumber)                               \
109   V(JSReceiver)                               \
110   V(Map)                                      \
111   V(Name)                                     \
112   V(PropertyCell)                             \
113   V(SharedFunctionInfo)                       \
114   V(SourceTextModule)                         \
115   /* Subtypes of Object */                    \
116   V(HeapObject)
117 
118 class CompilationDependencies;
119 struct FeedbackSource;
120 class JSHeapBroker;
121 class ObjectData;
122 class PerIsolateCompilerCache;
123 class PropertyAccessInfo;
124 #define FORWARD_DECL(Name) class Name##Ref;
125 HEAP_BROKER_SERIALIZED_OBJECT_LIST(FORWARD_DECL)
HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(FORWARD_DECL)126 HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(FORWARD_DECL)
127 #undef FORWARD_DECL
128 
129 class V8_EXPORT_PRIVATE ObjectRef {
130  public:
131   ObjectRef(JSHeapBroker* broker, Handle<Object> object,
132             bool check_type = true);
133   ObjectRef(JSHeapBroker* broker, ObjectData* data, bool check_type = true)
134       : data_(data), broker_(broker) {
135     CHECK_NOT_NULL(data_);
136   }
137 
138   Handle<Object> object() const;
139 
140   bool equals(const ObjectRef& other) const;
141 
142   bool IsSmi() const;
143   int AsSmi() const;
144 
145 #define HEAP_IS_METHOD_DECL(Name) bool Is##Name() const;
146   HEAP_BROKER_SERIALIZED_OBJECT_LIST(HEAP_IS_METHOD_DECL)
147   HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(HEAP_IS_METHOD_DECL)
148 #undef HEAP_IS_METHOD_DECL
149 
150 #define HEAP_AS_METHOD_DECL(Name) Name##Ref As##Name() const;
151   HEAP_BROKER_SERIALIZED_OBJECT_LIST(HEAP_AS_METHOD_DECL)
152   HEAP_BROKER_NEVER_SERIALIZED_OBJECT_LIST(HEAP_AS_METHOD_DECL)
153 #undef HEAP_AS_METHOD_DECL
154 
155   bool IsNullOrUndefined() const;
156   bool IsTheHole() const;
157 
158   bool BooleanValue() const;
159   Maybe<double> OddballToNumber() const;
160 
161   // Return the element at key {index} if {index} is known to be an own data
162   // property of the object that is non-writable and non-configurable.
163   base::Optional<ObjectRef> GetOwnConstantElement(
164       uint32_t index, SerializationPolicy policy =
165                           SerializationPolicy::kAssumeSerialized) const;
166 
167   Isolate* isolate() const;
168 
169   struct Hash {
170     size_t operator()(const ObjectRef& ref) const {
171       return base::hash_combine(ref.object().address());
172     }
173   };
174   struct Equal {
175     bool operator()(const ObjectRef& lhs, const ObjectRef& rhs) const {
176       return lhs.equals(rhs);
177     }
178   };
179 
180  protected:
181   JSHeapBroker* broker() const;
182   ObjectData* data() const;
183   ObjectData* data_;  // Should be used only by object() getters.
184 
185  private:
186   friend class FunctionTemplateInfoRef;
187   friend class JSArrayData;
188   friend class JSGlobalObjectData;
189   friend class JSGlobalObjectRef;
190   friend class JSHeapBroker;
191   friend class JSObjectData;
192   friend class StringData;
193 
194   friend std::ostream& operator<<(std::ostream& os, const ObjectRef& ref);
195 
196   JSHeapBroker* broker_;
197 };
198 
199 // Temporary class that carries information from a Map. We'd like to remove
200 // this class and use MapRef instead, but we can't as long as we support the
201 // kDisabled broker mode. That's because obtaining the MapRef via
202 // HeapObjectRef::map() requires a HandleScope when the broker is disabled.
203 // During OptimizeGraph we generally don't have a HandleScope, however. There
204 // are two places where we therefore use GetHeapObjectType() instead. Both that
205 // function and this class should eventually be removed.
206 class HeapObjectType {
207  public:
208   enum Flag : uint8_t { kUndetectable = 1 << 0, kCallable = 1 << 1 };
209 
210   using Flags = base::Flags<Flag>;
211 
HeapObjectType(InstanceType instance_type,Flags flags,OddballType oddball_type)212   HeapObjectType(InstanceType instance_type, Flags flags,
213                  OddballType oddball_type)
214       : instance_type_(instance_type),
215         oddball_type_(oddball_type),
216         flags_(flags) {
217     DCHECK_EQ(instance_type == ODDBALL_TYPE,
218               oddball_type != OddballType::kNone);
219   }
220 
oddball_type()221   OddballType oddball_type() const { return oddball_type_; }
instance_type()222   InstanceType instance_type() const { return instance_type_; }
flags()223   Flags flags() const { return flags_; }
224 
is_callable()225   bool is_callable() const { return flags_ & kCallable; }
is_undetectable()226   bool is_undetectable() const { return flags_ & kUndetectable; }
227 
228  private:
229   InstanceType const instance_type_;
230   OddballType const oddball_type_;
231   Flags const flags_;
232 };
233 
234 // Constructors are carefully defined such that we do a type check on
235 // the outermost Ref class in the inheritance chain only.
236 #define DEFINE_REF_CONSTRUCTOR(name, base)                                  \
237   name##Ref(JSHeapBroker* broker, Handle<Object> object,                    \
238             bool check_type = true)                                         \
239       : base(broker, object, false) {                                       \
240     if (check_type) {                                                       \
241       CHECK(Is##name());                                                    \
242     }                                                                       \
243   }                                                                         \
244   name##Ref(JSHeapBroker* broker, ObjectData* data, bool check_type = true) \
245       : base(broker, data, false) {                                         \
246     if (check_type) {                                                       \
247       CHECK(Is##name());                                                    \
248     }                                                                       \
249   }
250 
251 class HeapObjectRef : public ObjectRef {
252  public:
253   DEFINE_REF_CONSTRUCTOR(HeapObject, ObjectRef)
254 
255   Handle<HeapObject> object() const;
256 
257   MapRef map() const;
258 
259   // See the comment on the HeapObjectType class.
260   HeapObjectType GetHeapObjectType() const;
261 };
262 
263 class PropertyCellRef : public HeapObjectRef {
264  public:
265   DEFINE_REF_CONSTRUCTOR(PropertyCell, HeapObjectRef)
266 
267   Handle<PropertyCell> object() const;
268 
269   PropertyDetails property_details() const;
270 
271   void Serialize();
272   ObjectRef value() const;
273 };
274 
275 class JSReceiverRef : public HeapObjectRef {
276  public:
277   DEFINE_REF_CONSTRUCTOR(JSReceiver, HeapObjectRef)
278 
279   Handle<JSReceiver> object() const;
280 };
281 
282 class JSObjectRef : public JSReceiverRef {
283  public:
284   DEFINE_REF_CONSTRUCTOR(JSObject, JSReceiverRef)
285 
286   Handle<JSObject> object() const;
287 
288   uint64_t RawFastDoublePropertyAsBitsAt(FieldIndex index) const;
289   double RawFastDoublePropertyAt(FieldIndex index) const;
290   ObjectRef RawFastPropertyAt(FieldIndex index) const;
291 
292   // Return the value of the property identified by the field {index}
293   // if {index} is known to be an own data property of the object.
294   base::Optional<ObjectRef> GetOwnDataProperty(
295       Representation field_representation, FieldIndex index,
296       SerializationPolicy policy =
297           SerializationPolicy::kAssumeSerialized) const;
298   FixedArrayBaseRef elements() const;
299   void SerializeElements();
300   void EnsureElementsTenured();
301   ElementsKind GetElementsKind() const;
302 
303   void SerializeObjectCreateMap();
304   base::Optional<MapRef> GetObjectCreateMap() const;
305 };
306 
307 class JSDataViewRef : public JSObjectRef {
308  public:
309   DEFINE_REF_CONSTRUCTOR(JSDataView, JSObjectRef)
310 
311   Handle<JSDataView> object() const;
312 
313   size_t byte_length() const;
314 };
315 
316 class JSBoundFunctionRef : public JSObjectRef {
317  public:
318   DEFINE_REF_CONSTRUCTOR(JSBoundFunction, JSObjectRef)
319 
320   Handle<JSBoundFunction> object() const;
321 
322   bool Serialize();
323   bool serialized() const;
324 
325   // The following are available only after calling Serialize().
326   JSReceiverRef bound_target_function() const;
327   ObjectRef bound_this() const;
328   FixedArrayRef bound_arguments() const;
329 };
330 
331 class V8_EXPORT_PRIVATE JSFunctionRef : public JSObjectRef {
332  public:
333   DEFINE_REF_CONSTRUCTOR(JSFunction, JSObjectRef)
334 
335   Handle<JSFunction> object() const;
336 
337   bool has_feedback_vector() const;
338   bool has_initial_map() const;
339   bool has_prototype() const;
340   bool HasAttachedOptimizedCode() const;
341   bool PrototypeRequiresRuntimeLookup() const;
342 
343   void Serialize();
344   bool serialized() const;
345 
346   // The following are available only after calling Serialize().
347   ObjectRef prototype() const;
348   MapRef initial_map() const;
349   ContextRef context() const;
350   NativeContextRef native_context() const;
351   SharedFunctionInfoRef shared() const;
352   FeedbackVectorRef feedback_vector() const;
353   FeedbackCellRef raw_feedback_cell() const;
354   CodeRef code() const;
355   int InitialMapInstanceSizeWithMinSlack() const;
356 };
357 
358 class JSRegExpRef : public JSObjectRef {
359  public:
360   DEFINE_REF_CONSTRUCTOR(JSRegExp, JSObjectRef)
361 
362   Handle<JSRegExp> object() const;
363 
364   ObjectRef raw_properties_or_hash() const;
365   ObjectRef data() const;
366   ObjectRef source() const;
367   ObjectRef flags() const;
368   ObjectRef last_index() const;
369 
370   void SerializeAsRegExpBoilerplate();
371 };
372 
373 class HeapNumberRef : public HeapObjectRef {
374  public:
375   DEFINE_REF_CONSTRUCTOR(HeapNumber, HeapObjectRef)
376 
377   Handle<HeapNumber> object() const;
378 
379   double value() const;
380 };
381 
382 class ContextRef : public HeapObjectRef {
383  public:
384   DEFINE_REF_CONSTRUCTOR(Context, HeapObjectRef)
385 
386   Handle<Context> object() const;
387 
388   // {previous} decrements {depth} by 1 for each previous link successfully
389   // followed. If {depth} != 0 on function return, then it only got
390   // partway to the desired depth. If {serialize} is true, then
391   // {previous} will cache its findings.
392   ContextRef previous(size_t* depth,
393                       SerializationPolicy policy =
394                           SerializationPolicy::kAssumeSerialized) const;
395 
396   // Only returns a value if the index is valid for this ContextRef.
397   base::Optional<ObjectRef> get(
398       int index, SerializationPolicy policy =
399                      SerializationPolicy::kAssumeSerialized) const;
400 
401   SourceTextModuleRef GetModule(SerializationPolicy policy) const;
402 
403   // We only serialize the ScopeInfo if certain Promise
404   // builtins are called.
405   void SerializeScopeInfo();
406   base::Optional<ScopeInfoRef> scope_info() const;
407 };
408 
409 #define BROKER_COMPULSORY_NATIVE_CONTEXT_FIELDS(V) \
410   V(JSFunction, array_function)                    \
411   V(JSFunction, boolean_function)                  \
412   V(JSFunction, bigint_function)                   \
413   V(JSFunction, number_function)                   \
414   V(JSFunction, object_function)                   \
415   V(JSFunction, promise_function)                  \
416   V(JSFunction, promise_then)                      \
417   V(JSFunction, regexp_function)                   \
418   V(JSFunction, string_function)                   \
419   V(JSFunction, symbol_function)                   \
420   V(JSGlobalObject, global_object)                 \
421   V(JSGlobalProxy, global_proxy_object)            \
422   V(JSObject, promise_prototype)                   \
423   V(Map, block_context_map)                        \
424   V(Map, bound_function_with_constructor_map)      \
425   V(Map, bound_function_without_constructor_map)   \
426   V(Map, catch_context_map)                        \
427   V(Map, eval_context_map)                         \
428   V(Map, fast_aliased_arguments_map)               \
429   V(Map, function_context_map)                     \
430   V(Map, initial_array_iterator_map)               \
431   V(Map, initial_string_iterator_map)              \
432   V(Map, iterator_result_map)                      \
433   V(Map, js_array_holey_double_elements_map)       \
434   V(Map, js_array_holey_elements_map)              \
435   V(Map, js_array_holey_smi_elements_map)          \
436   V(Map, js_array_packed_double_elements_map)      \
437   V(Map, js_array_packed_elements_map)             \
438   V(Map, js_array_packed_smi_elements_map)         \
439   V(Map, sloppy_arguments_map)                     \
440   V(Map, slow_object_with_null_prototype_map)      \
441   V(Map, strict_arguments_map)                     \
442   V(Map, with_context_map)                         \
443   V(ScriptContextTable, script_context_table)
444 
445 // Those are set by Bootstrapper::ExportFromRuntime, which may not yet have
446 // happened when Turbofan is invoked via --always-opt.
447 #define BROKER_OPTIONAL_NATIVE_CONTEXT_FIELDS(V) \
448   V(Map, async_function_object_map)              \
449   V(Map, map_key_iterator_map)                   \
450   V(Map, map_key_value_iterator_map)             \
451   V(Map, map_value_iterator_map)                 \
452   V(JSFunction, regexp_exec_function)            \
453   V(Map, set_key_value_iterator_map)             \
454   V(Map, set_value_iterator_map)
455 
456 #define BROKER_NATIVE_CONTEXT_FIELDS(V)      \
457   BROKER_COMPULSORY_NATIVE_CONTEXT_FIELDS(V) \
458   BROKER_OPTIONAL_NATIVE_CONTEXT_FIELDS(V)
459 
460 class NativeContextRef : public ContextRef {
461  public:
462   DEFINE_REF_CONSTRUCTOR(NativeContext, ContextRef)
463 
464   Handle<NativeContext> object() const;
465 
466   void Serialize();
467 
468 #define DECL_ACCESSOR(type, name) type##Ref name() const;
469   BROKER_NATIVE_CONTEXT_FIELDS(DECL_ACCESSOR)
470 #undef DECL_ACCESSOR
471 
472   ScopeInfoRef scope_info() const;
473   MapRef GetFunctionMapFromIndex(int index) const;
474   MapRef GetInitialJSArrayMap(ElementsKind kind) const;
475   base::Optional<JSFunctionRef> GetConstructorFunction(const MapRef& map) const;
476 };
477 
478 class NameRef : public HeapObjectRef {
479  public:
480   DEFINE_REF_CONSTRUCTOR(Name, HeapObjectRef)
481 
482   Handle<Name> object() const;
483 
484   bool IsUniqueName() const;
485 };
486 
487 class ScriptContextTableRef : public HeapObjectRef {
488  public:
489   DEFINE_REF_CONSTRUCTOR(ScriptContextTable, HeapObjectRef)
490 
491   Handle<ScriptContextTable> object() const;
492 };
493 
494 class DescriptorArrayRef : public HeapObjectRef {
495  public:
496   DEFINE_REF_CONSTRUCTOR(DescriptorArray, HeapObjectRef)
497 
498   Handle<DescriptorArray> object() const;
499 };
500 
501 class FeedbackCellRef : public HeapObjectRef {
502  public:
503   DEFINE_REF_CONSTRUCTOR(FeedbackCell, HeapObjectRef)
504 
505   Handle<FeedbackCell> object() const;
506   base::Optional<SharedFunctionInfoRef> shared_function_info() const;
507   HeapObjectRef value() const;
508 };
509 
510 class FeedbackVectorRef : public HeapObjectRef {
511  public:
512   DEFINE_REF_CONSTRUCTOR(FeedbackVector, HeapObjectRef)
513 
514   Handle<FeedbackVector> object() const;
515 
516   SharedFunctionInfoRef shared_function_info() const;
517   double invocation_count() const;
518 
519   void Serialize();
520   bool serialized() const;
521   FeedbackCellRef GetClosureFeedbackCell(int index) const;
522 };
523 
524 class CallHandlerInfoRef : public HeapObjectRef {
525  public:
526   DEFINE_REF_CONSTRUCTOR(CallHandlerInfo, HeapObjectRef)
527 
528   Handle<CallHandlerInfo> object() const;
529 
530   Address callback() const;
531 
532   void Serialize();
533   ObjectRef data() const;
534 };
535 
536 class AccessorInfoRef : public HeapObjectRef {
537  public:
538   DEFINE_REF_CONSTRUCTOR(AccessorInfo, HeapObjectRef)
539 
540   Handle<AccessorInfo> object() const;
541 };
542 
543 class AllocationSiteRef : public HeapObjectRef {
544  public:
545   DEFINE_REF_CONSTRUCTOR(AllocationSite, HeapObjectRef)
546 
547   Handle<AllocationSite> object() const;
548 
549   bool PointsToLiteral() const;
550   AllocationType GetAllocationType() const;
551   ObjectRef nested_site() const;
552 
553   // {IsFastLiteral} determines whether the given array or object literal
554   // boilerplate satisfies all limits to be considered for fast deep-copying
555   // and computes the total size of all objects that are part of the graph.
556   //
557   // If PointsToLiteral() is false, then IsFastLiteral() is also false.
558   bool IsFastLiteral() const;
559 
560   void SerializeBoilerplate();
561 
562   // We only serialize boilerplate if IsFastLiteral is true.
563   base::Optional<JSObjectRef> boilerplate() const;
564 
565   ElementsKind GetElementsKind() const;
566   bool CanInlineCall() const;
567 };
568 
569 class BigIntRef : public HeapObjectRef {
570  public:
571   DEFINE_REF_CONSTRUCTOR(BigInt, HeapObjectRef)
572 
573   Handle<BigInt> object() const;
574 
575   uint64_t AsUint64() const;
576 };
577 
578 class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef {
579  public:
580   DEFINE_REF_CONSTRUCTOR(Map, HeapObjectRef)
581 
582   Handle<Map> object() const;
583 
584   int instance_size() const;
585   InstanceType instance_type() const;
586   int GetInObjectProperties() const;
587   int GetInObjectPropertiesStartInWords() const;
588   int NumberOfOwnDescriptors() const;
589   int GetInObjectPropertyOffset(int index) const;
590   int constructor_function_index() const;
591   int NextFreePropertyIndex() const;
592   int UnusedPropertyFields() const;
593   ElementsKind elements_kind() const;
594   bool is_stable() const;
595   bool is_extensible() const;
596   bool is_constructor() const;
597   bool has_prototype_slot() const;
598   bool is_access_check_needed() const;
599   bool is_deprecated() const;
600   bool CanBeDeprecated() const;
601   bool CanTransition() const;
602   bool IsInobjectSlackTrackingInProgress() const;
603   bool is_dictionary_map() const;
604   bool IsFixedCowArrayMap() const;
605   bool IsPrimitiveMap() const;
606   bool is_undetectable() const;
607   bool is_callable() const;
608   bool has_indexed_interceptor() const;
609   bool is_migration_target() const;
610   bool supports_fast_array_iteration() const;
611   bool supports_fast_array_resize() const;
612   bool is_abandoned_prototype_map() const;
613 
614   OddballType oddball_type() const;
615 
616 #define DEF_TESTER(Type, ...) bool Is##Type##Map() const;
617   INSTANCE_TYPE_CHECKERS(DEF_TESTER)
618 #undef DEF_TESTER
619 
620   void SerializeBackPointer();
621   HeapObjectRef GetBackPointer() const;
622 
623   void SerializePrototype();
624   bool serialized_prototype() const;
625   HeapObjectRef prototype() const;
626 
627   void SerializeForElementLoad();
628 
629   void SerializeForElementStore();
630   bool HasOnlyStablePrototypesWithFastElements(
631       ZoneVector<MapRef>* prototype_maps);
632 
633   // Concerning the underlying instance_descriptors:
634   void SerializeOwnDescriptors();
635   void SerializeOwnDescriptor(InternalIndex descriptor_index);
636   bool serialized_own_descriptor(InternalIndex descriptor_index) const;
637   MapRef FindFieldOwner(InternalIndex descriptor_index) const;
638   PropertyDetails GetPropertyDetails(InternalIndex descriptor_index) const;
639   NameRef GetPropertyKey(InternalIndex descriptor_index) const;
640   FieldIndex GetFieldIndexFor(InternalIndex descriptor_index) const;
641   ObjectRef GetFieldType(InternalIndex descriptor_index) const;
642   bool IsUnboxedDoubleField(InternalIndex descriptor_index) const;
643   base::Optional<ObjectRef> GetStrongValue(
644       InternalIndex descriptor_number) const;
645 
646   void SerializeRootMap();
647   base::Optional<MapRef> FindRootMap() const;
648 
649   // Available after calling JSFunctionRef::Serialize on a function that has
650   // this map as initial map.
651   ObjectRef GetConstructor() const;
652   base::Optional<MapRef> AsElementsKind(ElementsKind kind) const;
653 };
654 
655 struct HolderLookupResult {
656   HolderLookupResult(CallOptimization::HolderLookup lookup_ =
657                          CallOptimization::kHolderNotFound,
658                      base::Optional<JSObjectRef> holder_ = base::nullopt)
lookupHolderLookupResult659       : lookup(lookup_), holder(holder_) {}
660   CallOptimization::HolderLookup lookup;
661   base::Optional<JSObjectRef> holder;
662 };
663 
664 class FunctionTemplateInfoRef : public HeapObjectRef {
665  public:
666   DEFINE_REF_CONSTRUCTOR(FunctionTemplateInfo, HeapObjectRef)
667 
668   Handle<FunctionTemplateInfo> object() const;
669 
670   bool is_signature_undefined() const;
671   bool accept_any_receiver() const;
672   // The following returns true if the CallHandlerInfo is present.
673   bool has_call_code() const;
674 
675   void SerializeCallCode();
676   base::Optional<CallHandlerInfoRef> call_code() const;
677   Address c_function() const;
678   const CFunctionInfo* c_signature() const;
679 
680   HolderLookupResult LookupHolderOfExpectedType(
681       MapRef receiver_map,
682       SerializationPolicy policy = SerializationPolicy::kAssumeSerialized);
683 };
684 
685 class FixedArrayBaseRef : public HeapObjectRef {
686  public:
687   DEFINE_REF_CONSTRUCTOR(FixedArrayBase, HeapObjectRef)
688 
689   Handle<FixedArrayBase> object() const;
690 
691   int length() const;
692 };
693 
694 class ArrayBoilerplateDescriptionRef : public HeapObjectRef {
695  public:
696   using HeapObjectRef::HeapObjectRef;
697   Handle<ArrayBoilerplateDescription> object() const;
698 
699   int constants_elements_length() const;
700 };
701 
702 class ObjectBoilerplateDescriptionRef : public HeapObjectRef {
703  public:
704   using HeapObjectRef::HeapObjectRef;
705   Handle<ObjectBoilerplateDescription> object() const;
706 
707   int size() const;
708 };
709 
710 class FixedArrayRef : public FixedArrayBaseRef {
711  public:
712   DEFINE_REF_CONSTRUCTOR(FixedArray, FixedArrayBaseRef)
713 
714   Handle<FixedArray> object() const;
715 
716   ObjectRef get(int i) const;
717 };
718 
719 class FixedDoubleArrayRef : public FixedArrayBaseRef {
720  public:
721   DEFINE_REF_CONSTRUCTOR(FixedDoubleArray, FixedArrayBaseRef)
722 
723   Handle<FixedDoubleArray> object() const;
724 
725   Float64 get(int i) const;
726 };
727 
728 class BytecodeArrayRef : public FixedArrayBaseRef {
729  public:
730   DEFINE_REF_CONSTRUCTOR(BytecodeArray, FixedArrayBaseRef)
731 
732   Handle<BytecodeArray> object() const;
733 
734   int register_count() const;
735   int parameter_count() const;
736   interpreter::Register incoming_new_target_or_generator_register() const;
737 
738   // Bytecode access methods.
739   uint8_t get(int index) const;
740   Address GetFirstBytecodeAddress() const;
741 
742   Handle<ByteArray> SourcePositionTable() const;
743 
744   // Constant pool access.
745   Handle<Object> GetConstantAtIndex(int index) const;
746   bool IsConstantAtIndexSmi(int index) const;
747   Smi GetConstantAtIndexAsSmi(int index) const;
748 
749   // Exception handler table.
750   Address handler_table_address() const;
751   int handler_table_size() const;
752 
753   void SerializeForCompilation();
754 };
755 
756 class JSArrayRef : public JSObjectRef {
757  public:
758   DEFINE_REF_CONSTRUCTOR(JSArray, JSObjectRef)
759 
760   Handle<JSArray> object() const;
761 
762   ObjectRef length() const;
763 
764   // Return the element at key {index} if the array has a copy-on-write elements
765   // storage and {index} is known to be an own data property.
766   base::Optional<ObjectRef> GetOwnCowElement(
767       uint32_t index, SerializationPolicy policy =
768                           SerializationPolicy::kAssumeSerialized) const;
769 };
770 
771 class ScopeInfoRef : public HeapObjectRef {
772  public:
773   DEFINE_REF_CONSTRUCTOR(ScopeInfo, HeapObjectRef)
774 
775   Handle<ScopeInfo> object() const;
776 
777   int ContextLength() const;
778   bool HasOuterScopeInfo() const;
779   bool HasContextExtensionSlot() const;
780 
781   // Only serialized via SerializeScopeInfoChain.
782   ScopeInfoRef OuterScopeInfo() const;
783   void SerializeScopeInfoChain();
784 };
785 
786 #define BROKER_SFI_FIELDS(V)                             \
787   V(int, internal_formal_parameter_count)                \
788   V(bool, has_duplicate_parameters)                      \
789   V(int, function_map_index)                             \
790   V(FunctionKind, kind)                                  \
791   V(LanguageMode, language_mode)                         \
792   V(bool, native)                                        \
793   V(bool, HasBreakInfo)                                  \
794   V(bool, HasBuiltinId)                                  \
795   V(bool, construct_as_builtin)                          \
796   V(bool, HasBytecodeArray)                              \
797   V(int, StartPosition)                                  \
798   V(bool, is_compiled)                                   \
799   V(bool, IsUserJavaScript)
800 
801 class V8_EXPORT_PRIVATE SharedFunctionInfoRef : public HeapObjectRef {
802  public:
803   DEFINE_REF_CONSTRUCTOR(SharedFunctionInfo, HeapObjectRef)
804 
805   Handle<SharedFunctionInfo> object() const;
806 
807   int builtin_id() const;
808   int context_header_size() const;
809   BytecodeArrayRef GetBytecodeArray() const;
810   SharedFunctionInfo::Inlineability GetInlineability() const;
811 
812 #define DECL_ACCESSOR(type, name) type name() const;
BROKER_SFI_FIELDS(DECL_ACCESSOR)813   BROKER_SFI_FIELDS(DECL_ACCESSOR)
814 #undef DECL_ACCESSOR
815 
816   bool IsInlineable() const {
817     return GetInlineability() == SharedFunctionInfo::kIsInlineable;
818   }
819 
820   // Template objects may not be created at compilation time. This method
821   // wraps the retrieval of the template object and creates it if
822   // necessary.
823   JSArrayRef GetTemplateObject(
824       TemplateObjectDescriptionRef description, FeedbackSource const& source,
825       SerializationPolicy policy = SerializationPolicy::kAssumeSerialized);
826 
827   void SerializeFunctionTemplateInfo();
828   base::Optional<FunctionTemplateInfoRef> function_template_info() const;
829 
830   void SerializeScopeInfoChain();
831   ScopeInfoRef scope_info() const;
832 };
833 
834 class StringRef : public NameRef {
835  public:
836   DEFINE_REF_CONSTRUCTOR(String, NameRef)
837 
838   Handle<String> object() const;
839 
840   int length() const;
841   uint16_t GetFirstChar();
842   base::Optional<double> ToNumber();
843   bool IsSeqString() const;
844   bool IsExternalString() const;
845 };
846 
847 class SymbolRef : public NameRef {
848  public:
849   DEFINE_REF_CONSTRUCTOR(Symbol, NameRef)
850 
851   Handle<Symbol> object() const;
852 };
853 
854 class JSTypedArrayRef : public JSObjectRef {
855  public:
856   DEFINE_REF_CONSTRUCTOR(JSTypedArray, JSObjectRef)
857 
858   Handle<JSTypedArray> object() const;
859 
860   bool is_on_heap() const;
861   size_t length() const;
862   void* data_ptr() const;
863 
864   void Serialize();
865   bool serialized() const;
866 
867   HeapObjectRef buffer() const;
868 };
869 
870 class SourceTextModuleRef : public HeapObjectRef {
871  public:
872   DEFINE_REF_CONSTRUCTOR(SourceTextModule, HeapObjectRef)
873 
874   Handle<SourceTextModule> object() const;
875 
876   void Serialize();
877 
878   base::Optional<CellRef> GetCell(int cell_index) const;
879   ObjectRef import_meta() const;
880 };
881 
882 class TemplateObjectDescriptionRef : public HeapObjectRef {
883  public:
884   DEFINE_REF_CONSTRUCTOR(TemplateObjectDescription, HeapObjectRef)
885 
886   Handle<TemplateObjectDescription> object() const;
887 };
888 
889 class CellRef : public HeapObjectRef {
890  public:
891   DEFINE_REF_CONSTRUCTOR(Cell, HeapObjectRef)
892 
893   Handle<Cell> object() const;
894 };
895 
896 class JSGlobalObjectRef : public JSObjectRef {
897  public:
898   DEFINE_REF_CONSTRUCTOR(JSGlobalObject, JSObjectRef)
899 
900   Handle<JSGlobalObject> object() const;
901 
902   bool IsDetached() const;
903 
904   // If {serialize} is false:
905   //   If the property is known to exist as a property cell (on the global
906   //   object), return that property cell. Otherwise (not known to exist as a
907   //   property cell or known not to exist as a property cell) return nothing.
908   // If {serialize} is true:
909   //   Like above but potentially access the heap and serialize the necessary
910   //   information.
911   base::Optional<PropertyCellRef> GetPropertyCell(
912       NameRef const& name, SerializationPolicy policy =
913                                SerializationPolicy::kAssumeSerialized) const;
914 };
915 
916 class JSGlobalProxyRef : public JSObjectRef {
917  public:
918   DEFINE_REF_CONSTRUCTOR(JSGlobalProxy, JSObjectRef)
919 
920   Handle<JSGlobalProxy> object() const;
921 };
922 
923 class CodeRef : public HeapObjectRef {
924  public:
925   DEFINE_REF_CONSTRUCTOR(Code, HeapObjectRef)
926 
927   Handle<Code> object() const;
928 
929   unsigned inlined_bytecode_size() const;
930 };
931 
932 class InternalizedStringRef : public StringRef {
933  public:
934   DEFINE_REF_CONSTRUCTOR(InternalizedString, StringRef)
935 
936   Handle<InternalizedString> object() const;
937 };
938 
939 #undef DEFINE_REF_CONSTRUCTOR
940 
941 }  // namespace compiler
942 }  // namespace internal
943 }  // namespace v8
944 
945 #endif  // V8_COMPILER_HEAP_REFS_H_
946