Line data Source code
1 : // Copyright 2018 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_JS_HEAP_BROKER_H_
6 : #define V8_COMPILER_JS_HEAP_BROKER_H_
7 :
8 : #include "src/base/compiler-specific.h"
9 : #include "src/base/optional.h"
10 : #include "src/compiler/refs-map.h"
11 : #include "src/feedback-vector.h"
12 : #include "src/function-kind.h"
13 : #include "src/globals.h"
14 : #include "src/handles.h"
15 : #include "src/objects.h"
16 : #include "src/objects/instance-type.h"
17 : #include "src/ostreams.h"
18 : #include "src/zone/zone-containers.h"
19 :
20 : namespace v8 {
21 : namespace internal {
22 :
23 : class BytecodeArray;
24 : class VectorSlotPair;
25 : class FixedDoubleArray;
26 : class HeapNumber;
27 : class InternalizedString;
28 : class JSBoundFunction;
29 : class JSDataView;
30 : class JSGlobalProxy;
31 : class JSRegExp;
32 : class JSTypedArray;
33 : class NativeContext;
34 : class ScriptContextTable;
35 :
36 : namespace compiler {
37 :
38 : enum class OddballType : uint8_t {
39 : kNone, // Not an Oddball.
40 : kBoolean, // True or False.
41 : kUndefined,
42 : kNull,
43 : kHole,
44 : kUninitialized,
45 : kOther // Oddball, but none of the above.
46 : };
47 :
48 : // This list is sorted such that subtypes appear before their supertypes.
49 : // DO NOT VIOLATE THIS PROPERTY!
50 : #define HEAP_BROKER_OBJECT_LIST(V) \
51 : /* Subtypes of JSObject */ \
52 : V(JSArray) \
53 : V(JSBoundFunction) \
54 : V(JSDataView) \
55 : V(JSFunction) \
56 : V(JSGlobalProxy) \
57 : V(JSRegExp) \
58 : V(JSTypedArray) \
59 : /* Subtypes of Context */ \
60 : V(NativeContext) \
61 : /* Subtypes of FixedArray */ \
62 : V(Context) \
63 : V(ScopeInfo) \
64 : V(ScriptContextTable) \
65 : /* Subtypes of FixedArrayBase */ \
66 : V(BytecodeArray) \
67 : V(FixedArray) \
68 : V(FixedDoubleArray) \
69 : /* Subtypes of Name */ \
70 : V(InternalizedString) \
71 : V(String) \
72 : V(Symbol) \
73 : /* Subtypes of HeapObject */ \
74 : V(AllocationSite) \
75 : V(Cell) \
76 : V(Code) \
77 : V(DescriptorArray) \
78 : V(FeedbackVector) \
79 : V(FixedArrayBase) \
80 : V(HeapNumber) \
81 : V(JSObject) \
82 : V(Map) \
83 : V(Module) \
84 : V(MutableHeapNumber) \
85 : V(Name) \
86 : V(PropertyCell) \
87 : V(SharedFunctionInfo) \
88 : /* Subtypes of Object */ \
89 : V(HeapObject)
90 :
91 : class CompilationDependencies;
92 : class JSHeapBroker;
93 : class ObjectData;
94 : class PerIsolateCompilerCache;
95 : #define FORWARD_DECL(Name) class Name##Ref;
96 : HEAP_BROKER_OBJECT_LIST(FORWARD_DECL)
97 : #undef FORWARD_DECL
98 :
99 : class ObjectRef {
100 : public:
101 : ObjectRef(JSHeapBroker* broker, Handle<Object> object);
102 : ObjectRef(JSHeapBroker* broker, ObjectData* data)
103 465495 : : data_(data), broker_(broker) {
104 84748696 : CHECK_NOT_NULL(data_);
105 : }
106 :
107 : Handle<Object> object() const;
108 :
109 : bool equals(const ObjectRef& other) const;
110 :
111 : bool IsSmi() const;
112 : int AsSmi() const;
113 :
114 : #define HEAP_IS_METHOD_DECL(Name) bool Is##Name() const;
115 : HEAP_BROKER_OBJECT_LIST(HEAP_IS_METHOD_DECL)
116 : #undef HEAP_IS_METHOD_DECL
117 :
118 : #define HEAP_AS_METHOD_DECL(Name) Name##Ref As##Name() const;
119 : HEAP_BROKER_OBJECT_LIST(HEAP_AS_METHOD_DECL)
120 : #undef HEAP_AS_METHOD_DECL
121 :
122 : bool IsNullOrUndefined() const;
123 :
124 : bool BooleanValue() const;
125 : Maybe<double> OddballToNumber() const;
126 :
127 : Isolate* isolate() const;
128 :
129 : protected:
130 : JSHeapBroker* broker() const;
131 : ObjectData* data() const;
132 : ObjectData* data_; // Should be used only by object() getters.
133 :
134 : private:
135 : JSHeapBroker* broker_;
136 : };
137 :
138 : // Temporary class that carries information from a Map. We'd like to remove
139 : // this class and use MapRef instead, but we can't as long as we support the
140 : // kDisabled broker mode. That's because obtaining the MapRef via
141 : // HeapObjectRef::map() requires a HandleScope when the broker is disabled.
142 : // During OptimizeGraph we generally don't have a HandleScope, however. There
143 : // are two places where we therefore use GetHeapObjectType() instead. Both that
144 : // function and this class should eventually be removed.
145 : class HeapObjectType {
146 : public:
147 : enum Flag : uint8_t { kUndetectable = 1 << 0, kCallable = 1 << 1 };
148 :
149 : typedef base::Flags<Flag> Flags;
150 :
151 : HeapObjectType(InstanceType instance_type, Flags flags,
152 : OddballType oddball_type)
153 : : instance_type_(instance_type),
154 : oddball_type_(oddball_type),
155 : flags_(flags) {
156 : DCHECK_EQ(instance_type == ODDBALL_TYPE,
157 : oddball_type != OddballType::kNone);
158 : }
159 :
160 : OddballType oddball_type() const { return oddball_type_; }
161 : InstanceType instance_type() const { return instance_type_; }
162 : Flags flags() const { return flags_; }
163 :
164 : bool is_callable() const { return flags_ & kCallable; }
165 : bool is_undetectable() const { return flags_ & kUndetectable; }
166 :
167 : private:
168 : InstanceType const instance_type_;
169 : OddballType const oddball_type_;
170 : Flags const flags_;
171 : };
172 :
173 : class HeapObjectRef : public ObjectRef {
174 : public:
175 50445634 : using ObjectRef::ObjectRef;
176 : Handle<HeapObject> object() const;
177 :
178 : MapRef map() const;
179 :
180 : // See the comment on the HeapObjectType class.
181 : HeapObjectType GetHeapObjectType() const;
182 : };
183 :
184 : class PropertyCellRef : public HeapObjectRef {
185 : public:
186 : using HeapObjectRef::HeapObjectRef;
187 : Handle<PropertyCell> object() const;
188 :
189 : PropertyDetails property_details() const;
190 :
191 : void Serialize();
192 : ObjectRef value() const;
193 : };
194 :
195 : class JSObjectRef : public HeapObjectRef {
196 : public:
197 : using HeapObjectRef::HeapObjectRef;
198 : Handle<JSObject> object() const;
199 :
200 : double RawFastDoublePropertyAt(FieldIndex index) const;
201 : ObjectRef RawFastPropertyAt(FieldIndex index) const;
202 :
203 : FixedArrayBaseRef elements() const;
204 : void EnsureElementsTenured();
205 : ElementsKind GetElementsKind() const;
206 :
207 : void SerializeObjectCreateMap();
208 : base::Optional<MapRef> GetObjectCreateMap() const;
209 : };
210 :
211 : class JSDataViewRef : public JSObjectRef {
212 : public:
213 : using JSObjectRef::JSObjectRef;
214 : Handle<JSDataView> object() const;
215 :
216 : size_t byte_length() const;
217 : size_t byte_offset() const;
218 : };
219 :
220 : class JSBoundFunctionRef : public JSObjectRef {
221 : public:
222 : using JSObjectRef::JSObjectRef;
223 : Handle<JSBoundFunction> object() const;
224 :
225 : void Serialize();
226 :
227 : // The following are available only after calling Serialize().
228 : ObjectRef bound_target_function() const;
229 : ObjectRef bound_this() const;
230 : FixedArrayRef bound_arguments() const;
231 : };
232 :
233 : class JSFunctionRef : public JSObjectRef {
234 : public:
235 : using JSObjectRef::JSObjectRef;
236 : Handle<JSFunction> object() const;
237 :
238 : bool has_feedback_vector() const;
239 : bool has_initial_map() const;
240 : bool has_prototype() const;
241 : bool PrototypeRequiresRuntimeLookup() const;
242 :
243 : void Serialize();
244 : bool IsSerializedForCompilation() const;
245 :
246 : // The following are available only after calling Serialize().
247 : ObjectRef prototype() const;
248 : MapRef initial_map() const;
249 : ContextRef context() const;
250 : NativeContextRef native_context() const;
251 : SharedFunctionInfoRef shared() const;
252 : FeedbackVectorRef feedback_vector() const;
253 : int InitialMapInstanceSizeWithMinSlack() const;
254 : };
255 :
256 : class JSRegExpRef : public JSObjectRef {
257 : public:
258 : using JSObjectRef::JSObjectRef;
259 : Handle<JSRegExp> object() const;
260 :
261 : ObjectRef raw_properties_or_hash() const;
262 : ObjectRef data() const;
263 : ObjectRef source() const;
264 : ObjectRef flags() const;
265 : ObjectRef last_index() const;
266 : };
267 :
268 : class HeapNumberRef : public HeapObjectRef {
269 : public:
270 : using HeapObjectRef::HeapObjectRef;
271 : Handle<HeapNumber> object() const;
272 :
273 : double value() const;
274 : };
275 :
276 : class MutableHeapNumberRef : public HeapObjectRef {
277 : public:
278 : using HeapObjectRef::HeapObjectRef;
279 : Handle<MutableHeapNumber> object() const;
280 :
281 : double value() const;
282 : };
283 :
284 : class ContextRef : public HeapObjectRef {
285 : public:
286 : using HeapObjectRef::HeapObjectRef;
287 : Handle<Context> object() const;
288 :
289 : void SerializeContextChain();
290 : ContextRef previous() const;
291 :
292 : void SerializeSlot(int index);
293 : ObjectRef get(int index) const;
294 : };
295 :
296 : #define BROKER_COMPULSORY_NATIVE_CONTEXT_FIELDS(V) \
297 : V(JSFunction, array_function) \
298 : V(JSFunction, boolean_function) \
299 : V(JSFunction, bigint_function) \
300 : V(JSFunction, number_function) \
301 : V(JSFunction, object_function) \
302 : V(JSFunction, promise_function) \
303 : V(JSFunction, promise_then) \
304 : V(JSFunction, string_function) \
305 : V(JSFunction, symbol_function) \
306 : V(JSGlobalProxy, global_proxy_object) \
307 : V(JSObject, promise_prototype) \
308 : V(Map, bound_function_with_constructor_map) \
309 : V(Map, bound_function_without_constructor_map) \
310 : V(Map, fast_aliased_arguments_map) \
311 : V(Map, initial_array_iterator_map) \
312 : V(Map, initial_string_iterator_map) \
313 : V(Map, iterator_result_map) \
314 : V(Map, js_array_holey_double_elements_map) \
315 : V(Map, js_array_holey_elements_map) \
316 : V(Map, js_array_holey_smi_elements_map) \
317 : V(Map, js_array_packed_double_elements_map) \
318 : V(Map, js_array_packed_elements_map) \
319 : V(Map, js_array_packed_smi_elements_map) \
320 : V(Map, sloppy_arguments_map) \
321 : V(Map, slow_object_with_null_prototype_map) \
322 : V(Map, strict_arguments_map) \
323 : V(ScriptContextTable, script_context_table) \
324 : V(SharedFunctionInfo, promise_capability_default_reject_shared_fun) \
325 : V(SharedFunctionInfo, promise_catch_finally_shared_fun) \
326 : V(SharedFunctionInfo, promise_then_finally_shared_fun) \
327 : V(SharedFunctionInfo, promise_capability_default_resolve_shared_fun)
328 :
329 : // Those are set by Bootstrapper::ExportFromRuntime, which may not yet have
330 : // happened when Turbofan is invoked via --always-opt.
331 : #define BROKER_OPTIONAL_NATIVE_CONTEXT_FIELDS(V) \
332 : V(Map, async_function_object_map) \
333 : V(Map, map_key_iterator_map) \
334 : V(Map, map_key_value_iterator_map) \
335 : V(Map, map_value_iterator_map) \
336 : V(Map, set_key_value_iterator_map) \
337 : V(Map, set_value_iterator_map)
338 :
339 : #define BROKER_NATIVE_CONTEXT_FIELDS(V) \
340 : BROKER_COMPULSORY_NATIVE_CONTEXT_FIELDS(V) \
341 : BROKER_OPTIONAL_NATIVE_CONTEXT_FIELDS(V)
342 :
343 : class NativeContextRef : public ContextRef {
344 : public:
345 : using ContextRef::ContextRef;
346 : Handle<NativeContext> object() const;
347 :
348 : void Serialize();
349 :
350 : #define DECL_ACCESSOR(type, name) type##Ref name() const;
351 : BROKER_NATIVE_CONTEXT_FIELDS(DECL_ACCESSOR)
352 : #undef DECL_ACCESSOR
353 :
354 : MapRef GetFunctionMapFromIndex(int index) const;
355 : MapRef GetInitialJSArrayMap(ElementsKind kind) const;
356 : base::Optional<JSFunctionRef> GetConstructorFunction(const MapRef& map) const;
357 : };
358 :
359 : class NameRef : public HeapObjectRef {
360 : public:
361 : using HeapObjectRef::HeapObjectRef;
362 : Handle<Name> object() const;
363 : };
364 :
365 : class ScriptContextTableRef : public HeapObjectRef {
366 : public:
367 : using HeapObjectRef::HeapObjectRef;
368 : Handle<ScriptContextTable> object() const;
369 :
370 : struct LookupResult {
371 : ContextRef context;
372 : bool immutable;
373 : int index;
374 : };
375 :
376 : base::Optional<LookupResult> lookup(const NameRef& name) const;
377 : };
378 :
379 : class DescriptorArrayRef : public HeapObjectRef {
380 : public:
381 : using HeapObjectRef::HeapObjectRef;
382 : Handle<DescriptorArray> object() const;
383 : };
384 :
385 : class FeedbackVectorRef : public HeapObjectRef {
386 : public:
387 : using HeapObjectRef::HeapObjectRef;
388 : Handle<FeedbackVector> object() const;
389 :
390 : ObjectRef get(FeedbackSlot slot) const;
391 :
392 : void SerializeSlots();
393 : };
394 :
395 : class AllocationSiteRef : public HeapObjectRef {
396 : public:
397 : using HeapObjectRef::HeapObjectRef;
398 : Handle<AllocationSite> object() const;
399 :
400 : bool PointsToLiteral() const;
401 : AllocationType GetAllocationType() const;
402 : ObjectRef nested_site() const;
403 :
404 : // {IsFastLiteral} determines whether the given array or object literal
405 : // boilerplate satisfies all limits to be considered for fast deep-copying
406 : // and computes the total size of all objects that are part of the graph.
407 : //
408 : // If PointsToLiteral() is false, then IsFastLiteral() is also false.
409 : bool IsFastLiteral() const;
410 : // We only serialize boilerplate if IsFastLiteral is true.
411 : base::Optional<JSObjectRef> boilerplate() const;
412 :
413 : ElementsKind GetElementsKind() const;
414 : bool CanInlineCall() const;
415 : };
416 :
417 : class MapRef : public HeapObjectRef {
418 : public:
419 : using HeapObjectRef::HeapObjectRef;
420 : Handle<Map> object() const;
421 :
422 : int instance_size() const;
423 : InstanceType instance_type() const;
424 : int GetInObjectProperties() const;
425 : int GetInObjectPropertiesStartInWords() const;
426 : int NumberOfOwnDescriptors() const;
427 : int GetInObjectPropertyOffset(int index) const;
428 : int constructor_function_index() const;
429 : int NextFreePropertyIndex() const;
430 : int UnusedPropertyFields() const;
431 : ElementsKind elements_kind() const;
432 : bool is_stable() const;
433 : bool is_extensible() const;
434 : bool is_constructor() const;
435 : bool has_prototype_slot() const;
436 : bool is_access_check_needed() const;
437 : bool is_deprecated() const;
438 : bool CanBeDeprecated() const;
439 : bool CanTransition() const;
440 : bool IsInobjectSlackTrackingInProgress() const;
441 : bool is_dictionary_map() const;
442 : bool IsFixedCowArrayMap() const;
443 : bool IsPrimitiveMap() const;
444 : bool is_undetectable() const;
445 : bool is_callable() const;
446 : bool has_indexed_interceptor() const;
447 : bool has_hidden_prototype() const;
448 : bool is_migration_target() const;
449 : bool supports_fast_array_iteration() const;
450 : bool supports_fast_array_resize() const;
451 :
452 : #define DEF_TESTER(Type, ...) bool Is##Type##Map() const;
453 : INSTANCE_TYPE_CHECKERS(DEF_TESTER)
454 : #undef DEF_TESTER
455 :
456 : ObjectRef GetConstructor() const;
457 : OddballType oddball_type() const;
458 : base::Optional<MapRef> AsElementsKind(ElementsKind kind) const;
459 :
460 : void SerializePrototype();
461 : ObjectRef prototype() const;
462 :
463 : void SerializeForElementLoad();
464 :
465 : void SerializeForElementStore();
466 : bool HasOnlyStablePrototypesWithFastElements(
467 : ZoneVector<MapRef>* prototype_maps);
468 :
469 : // Concerning the underlying instance_descriptors:
470 : void SerializeOwnDescriptors();
471 : MapRef FindFieldOwner(int descriptor_index) const;
472 : PropertyDetails GetPropertyDetails(int descriptor_index) const;
473 : NameRef GetPropertyKey(int descriptor_index) const;
474 : FieldIndex GetFieldIndexFor(int descriptor_index) const;
475 : ObjectRef GetFieldType(int descriptor_index) const;
476 : bool IsUnboxedDoubleField(int descriptor_index) const;
477 : };
478 :
479 : class FixedArrayBaseRef : public HeapObjectRef {
480 : public:
481 : using HeapObjectRef::HeapObjectRef;
482 : Handle<FixedArrayBase> object() const;
483 :
484 : int length() const;
485 : };
486 :
487 : class FixedArrayRef : public FixedArrayBaseRef {
488 : public:
489 : using FixedArrayBaseRef::FixedArrayBaseRef;
490 : Handle<FixedArray> object() const;
491 :
492 : ObjectRef get(int i) const;
493 : };
494 :
495 : class FixedDoubleArrayRef : public FixedArrayBaseRef {
496 : public:
497 : using FixedArrayBaseRef::FixedArrayBaseRef;
498 : Handle<FixedDoubleArray> object() const;
499 :
500 : double get_scalar(int i) const;
501 : bool is_the_hole(int i) const;
502 : };
503 :
504 : class BytecodeArrayRef : public FixedArrayBaseRef {
505 : public:
506 : using FixedArrayBaseRef::FixedArrayBaseRef;
507 : Handle<BytecodeArray> object() const;
508 :
509 : int register_count() const;
510 : };
511 :
512 : class JSArrayRef : public JSObjectRef {
513 : public:
514 : using JSObjectRef::JSObjectRef;
515 : Handle<JSArray> object() const;
516 :
517 : ObjectRef length() const;
518 : };
519 :
520 : class ScopeInfoRef : public HeapObjectRef {
521 : public:
522 : using HeapObjectRef::HeapObjectRef;
523 : Handle<ScopeInfo> object() const;
524 :
525 : int ContextLength() const;
526 : };
527 :
528 : #define BROKER_SFI_FIELDS(V) \
529 : V(int, internal_formal_parameter_count) \
530 : V(bool, has_duplicate_parameters) \
531 : V(int, function_map_index) \
532 : V(FunctionKind, kind) \
533 : V(LanguageMode, language_mode) \
534 : V(bool, native) \
535 : V(bool, HasBreakInfo) \
536 : V(bool, HasBuiltinId) \
537 : V(bool, construct_as_builtin) \
538 : V(bool, HasBytecodeArray) \
539 : V(bool, is_safe_to_skip_arguments_adaptor) \
540 : V(bool, IsInlineable)
541 :
542 : class SharedFunctionInfoRef : public HeapObjectRef {
543 : public:
544 : using HeapObjectRef::HeapObjectRef;
545 : Handle<SharedFunctionInfo> object() const;
546 :
547 : int builtin_id() const;
548 : BytecodeArrayRef GetBytecodeArray() const;
549 :
550 : #define DECL_ACCESSOR(type, name) type name() const;
551 : BROKER_SFI_FIELDS(DECL_ACCESSOR)
552 : #undef DECL_ACCESSOR
553 :
554 : bool IsSerializedForCompilation(FeedbackVectorRef feedback) const;
555 : void SetSerializedForCompilation(FeedbackVectorRef feedback);
556 : };
557 :
558 : class StringRef : public NameRef {
559 : public:
560 : using NameRef::NameRef;
561 : Handle<String> object() const;
562 :
563 : int length() const;
564 : uint16_t GetFirstChar();
565 : base::Optional<double> ToNumber();
566 : bool IsSeqString() const;
567 : bool IsExternalString() const;
568 : };
569 :
570 : class SymbolRef : public NameRef {
571 : public:
572 : using NameRef::NameRef;
573 : Handle<Symbol> object() const;
574 : };
575 :
576 : class JSTypedArrayRef : public JSObjectRef {
577 : public:
578 : using JSObjectRef::JSObjectRef;
579 : Handle<JSTypedArray> object() const;
580 :
581 : bool is_on_heap() const;
582 : size_t length_value() const;
583 : void* elements_external_pointer() const;
584 :
585 : void Serialize();
586 : bool serialized() const;
587 :
588 : HeapObjectRef buffer() const;
589 : };
590 :
591 : class ModuleRef : public HeapObjectRef {
592 : public:
593 : using HeapObjectRef::HeapObjectRef;
594 : Handle<Module> object() const;
595 :
596 : void Serialize();
597 :
598 : CellRef GetCell(int cell_index) const;
599 : };
600 :
601 : class CellRef : public HeapObjectRef {
602 : public:
603 : using HeapObjectRef::HeapObjectRef;
604 : Handle<Cell> object() const;
605 :
606 : ObjectRef value() const;
607 : };
608 :
609 : class JSGlobalProxyRef : public JSObjectRef {
610 : public:
611 : using JSObjectRef::JSObjectRef;
612 : Handle<JSGlobalProxy> object() const;
613 : };
614 :
615 : class CodeRef : public HeapObjectRef {
616 : public:
617 : using HeapObjectRef::HeapObjectRef;
618 : Handle<Code> object() const;
619 : };
620 :
621 : class InternalizedStringRef : public StringRef {
622 : public:
623 : using StringRef::StringRef;
624 : Handle<InternalizedString> object() const;
625 :
626 : uint32_t array_index() const;
627 : static const uint32_t kNotAnArrayIndex = -1; // 2^32-1 is not a valid index.
628 : };
629 :
630 : class ProcessedFeedback : public ZoneObject {
631 : public:
632 : enum Kind { kElementAccess, kGlobalAccess };
633 0 : Kind kind() const { return kind_; }
634 :
635 : protected:
636 215989 : explicit ProcessedFeedback(Kind kind) : kind_(kind) {}
637 :
638 : private:
639 : Kind const kind_;
640 : };
641 :
642 : class GlobalAccessFeedback : public ProcessedFeedback {
643 : public:
644 : explicit GlobalAccessFeedback(PropertyCellRef cell);
645 : GlobalAccessFeedback(ContextRef script_context, int slot_index,
646 : bool immutable);
647 :
648 : bool IsPropertyCell() const;
649 : PropertyCellRef property_cell() const;
650 :
651 192850 : bool IsScriptContextSlot() const { return !IsPropertyCell(); }
652 : ContextRef script_context() const;
653 : int slot_index() const;
654 : bool immutable() const;
655 :
656 : base::Optional<ObjectRef> GetConstantValue() const;
657 :
658 : private:
659 : ObjectRef const cell_or_context_;
660 : int const index_and_immutable_;
661 : };
662 :
663 : class ElementAccessFeedback : public ProcessedFeedback {
664 : public:
665 : explicit ElementAccessFeedback(Zone* zone);
666 :
667 : // No transition sources appear in {receiver_maps}.
668 : // All transition targets appear in {receiver_maps}.
669 : ZoneVector<Handle<Map>> receiver_maps;
670 : ZoneVector<std::pair<Handle<Map>, Handle<Map>>> transitions;
671 :
672 : class MapIterator {
673 : public:
674 : bool done() const;
675 : void advance();
676 : MapRef current() const;
677 :
678 : private:
679 : friend class ElementAccessFeedback;
680 :
681 : explicit MapIterator(ElementAccessFeedback const& processed,
682 : JSHeapBroker* broker);
683 :
684 : ElementAccessFeedback const& processed_;
685 : JSHeapBroker* const broker_;
686 : size_t index_ = 0;
687 : };
688 :
689 : // Iterator over all maps: first {receiver_maps}, then transition sources.
690 : MapIterator all_maps(JSHeapBroker* broker) const;
691 : };
692 :
693 : struct FeedbackSource {
694 : FeedbackSource(Handle<FeedbackVector> vector_, FeedbackSlot slot_)
695 51 : : vector(vector_), slot(slot_) {}
696 : explicit FeedbackSource(FeedbackNexus const& nexus);
697 : explicit FeedbackSource(VectorSlotPair const& pair);
698 :
699 : Handle<FeedbackVector> const vector;
700 : FeedbackSlot const slot;
701 :
702 : struct Hash {
703 189 : size_t operator()(FeedbackSource const& source) const {
704 189 : return base::hash_combine(source.vector.address(), source.slot);
705 : }
706 : };
707 :
708 : struct Equal {
709 : bool operator()(FeedbackSource const& lhs,
710 : FeedbackSource const& rhs) const {
711 126 : return lhs.vector.equals(rhs.vector) && lhs.slot == rhs.slot;
712 : }
713 : };
714 : };
715 :
716 9060 : class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) {
717 : public:
718 : JSHeapBroker(Isolate* isolate, Zone* broker_zone);
719 :
720 : void SetNativeContextRef();
721 : void SerializeStandardObjects();
722 :
723 : Isolate* isolate() const { return isolate_; }
724 : Zone* zone() const { return current_zone_; }
725 1728298 : NativeContextRef native_context() const { return native_context_.value(); }
726 : PerIsolateCompilerCache* compiler_cache() const { return compiler_cache_; }
727 :
728 : enum BrokerMode { kDisabled, kSerializing, kSerialized, kRetired };
729 : BrokerMode mode() const { return mode_; }
730 : void StartSerializing();
731 : void StopSerializing();
732 : void Retire();
733 : bool SerializingAllowed() const;
734 :
735 : // Returns nullptr iff handle unknown.
736 : ObjectData* GetData(Handle<Object>) const;
737 : // Never returns nullptr.
738 : ObjectData* GetOrCreateData(Handle<Object>);
739 : // Like the previous but wraps argument in handle first (for convenience).
740 : ObjectData* GetOrCreateData(Object);
741 :
742 : // Check if {object} is any native context's %ArrayPrototype% or
743 : // %ObjectPrototype%.
744 : bool IsArrayOrObjectPrototype(const JSObjectRef& object) const;
745 :
746 : bool HasFeedback(FeedbackSource const& source) const;
747 : // The processed {feedback} can be {nullptr}, indicating that the original
748 : // feedback didn't contain information relevant for Turbofan.
749 : void SetFeedback(FeedbackSource const& source,
750 : ProcessedFeedback const* feedback);
751 : ProcessedFeedback const* GetFeedback(FeedbackSource const& source) const;
752 :
753 : // Convenience wrappers around GetFeedback.
754 : ElementAccessFeedback const* GetElementAccessFeedback(
755 : FeedbackSource const& source) const;
756 : GlobalAccessFeedback const* GetGlobalAccessFeedback(
757 : FeedbackSource const& source) const;
758 :
759 : // TODO(neis): Move these into serializer when we're always in the background.
760 : ElementAccessFeedback const* ProcessFeedbackMapsForElementAccess(
761 : MapHandles const& maps);
762 : GlobalAccessFeedback const* ProcessFeedbackForGlobalAccess(
763 : FeedbackSource const& source);
764 :
765 : std::ostream& Trace();
766 : void IncrementTracingIndentation();
767 : void DecrementTracingIndentation();
768 :
769 : private:
770 : friend class HeapObjectRef;
771 : friend class ObjectRef;
772 : friend class ObjectData;
773 :
774 : void SerializeShareableObjects();
775 : void CollectArrayAndObjectPrototypes();
776 :
777 : Isolate* const isolate_;
778 : Zone* const broker_zone_;
779 : Zone* current_zone_;
780 : base::Optional<NativeContextRef> native_context_;
781 : RefsMap* refs_;
782 : ZoneUnorderedSet<Handle<JSObject>, Handle<JSObject>::hash,
783 : Handle<JSObject>::equal_to>
784 : array_and_object_prototypes_;
785 : BrokerMode mode_ = kDisabled;
786 : StdoutStream trace_out_;
787 : unsigned trace_indentation_ = 0;
788 : PerIsolateCompilerCache* compiler_cache_;
789 : ZoneUnorderedMap<FeedbackSource, ProcessedFeedback const*,
790 : FeedbackSource::Hash, FeedbackSource::Equal>
791 : feedback_;
792 :
793 : static const size_t kMinimalRefsBucketCount = 8; // must be power of 2
794 : static const size_t kInitialRefsBucketCount = 1024; // must be power of 2
795 : };
796 :
797 : #define ASSIGN_RETURN_NO_CHANGE_IF_DATA_MISSING(something_var, \
798 : optionally_something) \
799 : auto optionally_something_ = optionally_something; \
800 : if (!optionally_something_) \
801 : return NoChangeBecauseOfMissingData(broker(), __FUNCTION__, __LINE__); \
802 : something_var = *optionally_something_;
803 :
804 : class Reduction;
805 : Reduction NoChangeBecauseOfMissingData(JSHeapBroker* broker,
806 : const char* function, int line);
807 :
808 : // Miscellaneous definitions that should be moved elsewhere once concurrent
809 : // compilation is finished.
810 : bool CanInlineElementAccess(MapRef const& map);
811 :
812 : #define TRACE_BROKER(broker, x) \
813 : do { \
814 : if (FLAG_trace_heap_broker) broker->Trace() << x << '\n'; \
815 : } while (false)
816 :
817 : } // namespace compiler
818 : } // namespace internal
819 : } // namespace v8
820 :
821 : #endif // V8_COMPILER_JS_HEAP_BROKER_H_
|