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