Line data Source code
1 : // Copyright 2015 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 : #include "src/compiler/compilation-dependencies.h"
6 :
7 : #include "src/handles-inl.h"
8 : #include "src/objects-inl.h"
9 : #include "src/objects/allocation-site-inl.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 : namespace compiler {
14 :
15 482967 : CompilationDependencies::CompilationDependencies(JSHeapBroker* broker,
16 : Zone* zone)
17 965934 : : zone_(zone), broker_(broker), dependencies_(zone) {}
18 :
19 476583 : class CompilationDependencies::Dependency : public ZoneObject {
20 : public:
21 : virtual bool IsValid() const = 0;
22 467066 : virtual void PrepareInstall() {}
23 : virtual void Install(const MaybeObjectHandle& code) = 0;
24 :
25 : #ifdef DEBUG
26 : virtual bool IsPretenureModeDependency() const { return false; }
27 : #endif
28 : };
29 :
30 : class InitialMapDependency final : public CompilationDependencies::Dependency {
31 : public:
32 : // TODO(neis): Once the concurrent compiler frontend is always-on, we no
33 : // longer need to explicitly store the initial map.
34 : InitialMapDependency(const JSFunctionRef& function, const MapRef& initial_map)
35 5058 : : function_(function), initial_map_(initial_map) {
36 : DCHECK(function_.has_initial_map());
37 : DCHECK(function_.initial_map().equals(initial_map_));
38 : }
39 :
40 10053 : bool IsValid() const override {
41 10053 : Handle<JSFunction> function = function_.object();
42 20106 : return function->has_initial_map() &&
43 20106 : function->initial_map() == *initial_map_.object();
44 : }
45 :
46 5025 : void Install(const MaybeObjectHandle& code) override {
47 : SLOW_DCHECK(IsValid());
48 15075 : DependentCode::InstallDependency(function_.isolate(), code,
49 : initial_map_.object(),
50 5025 : DependentCode::kInitialMapChangedGroup);
51 5025 : }
52 :
53 : private:
54 : JSFunctionRef function_;
55 : MapRef initial_map_;
56 : };
57 :
58 : class PrototypePropertyDependency final
59 : : public CompilationDependencies::Dependency {
60 : public:
61 : // TODO(neis): Once the concurrent compiler frontend is always-on, we no
62 : // longer need to explicitly store the prototype.
63 : PrototypePropertyDependency(const JSFunctionRef& function,
64 : const ObjectRef& prototype)
65 1319 : : function_(function), prototype_(prototype) {
66 : DCHECK(function_.has_prototype());
67 : DCHECK(!function_.PrototypeRequiresRuntimeLookup());
68 : DCHECK(function_.prototype().equals(prototype_));
69 : }
70 :
71 2618 : bool IsValid() const override {
72 2618 : Handle<JSFunction> function = function_.object();
73 10472 : return function->has_prototype_slot() && function->has_prototype() &&
74 7854 : !function->PrototypeRequiresRuntimeLookup() &&
75 7854 : function->prototype() == *prototype_.object();
76 : }
77 :
78 1316 : void PrepareInstall() override {
79 : SLOW_DCHECK(IsValid());
80 1316 : Handle<JSFunction> function = function_.object();
81 1316 : if (!function->has_initial_map()) JSFunction::EnsureHasInitialMap(function);
82 1316 : }
83 :
84 1302 : void Install(const MaybeObjectHandle& code) override {
85 : SLOW_DCHECK(IsValid());
86 1302 : Handle<JSFunction> function = function_.object();
87 : DCHECK(function->has_initial_map());
88 1302 : Handle<Map> initial_map(function->initial_map(), function_.isolate());
89 2604 : DependentCode::InstallDependency(function_.isolate(), code, initial_map,
90 1302 : DependentCode::kInitialMapChangedGroup);
91 1302 : }
92 :
93 : private:
94 : JSFunctionRef function_;
95 : ObjectRef prototype_;
96 : };
97 :
98 : class StableMapDependency final : public CompilationDependencies::Dependency {
99 : public:
100 158757 : explicit StableMapDependency(const MapRef& map) : map_(map) {
101 : DCHECK(map_.is_stable());
102 : }
103 :
104 631984 : bool IsValid() const override { return map_.object()->is_stable(); }
105 :
106 157963 : void Install(const MaybeObjectHandle& code) override {
107 : SLOW_DCHECK(IsValid());
108 473889 : DependentCode::InstallDependency(map_.isolate(), code, map_.object(),
109 157963 : DependentCode::kPrototypeCheckGroup);
110 157963 : }
111 :
112 : private:
113 : MapRef map_;
114 : };
115 :
116 : class TransitionDependency final : public CompilationDependencies::Dependency {
117 : public:
118 19102 : explicit TransitionDependency(const MapRef& map) : map_(map) {
119 : DCHECK(!map_.is_deprecated());
120 : }
121 :
122 76312 : bool IsValid() const override { return !map_.object()->is_deprecated(); }
123 :
124 19076 : void Install(const MaybeObjectHandle& code) override {
125 : SLOW_DCHECK(IsValid());
126 57228 : DependentCode::InstallDependency(map_.isolate(), code, map_.object(),
127 19076 : DependentCode::kTransitionGroup);
128 19076 : }
129 :
130 : private:
131 : MapRef map_;
132 : };
133 :
134 : class PretenureModeDependency final
135 : : public CompilationDependencies::Dependency {
136 : public:
137 : // TODO(neis): Once the concurrent compiler frontend is always-on, we no
138 : // longer need to explicitly store the mode.
139 : PretenureModeDependency(const AllocationSiteRef& site,
140 : AllocationType allocation)
141 7250 : : site_(site), allocation_(allocation) {
142 : DCHECK_EQ(allocation, site_.GetAllocationType());
143 : }
144 :
145 14259 : bool IsValid() const override {
146 28518 : return allocation_ == site_.object()->GetAllocationType();
147 : }
148 :
149 7123 : void Install(const MaybeObjectHandle& code) override {
150 : SLOW_DCHECK(IsValid());
151 21369 : DependentCode::InstallDependency(
152 : site_.isolate(), code, site_.object(),
153 7123 : DependentCode::kAllocationSiteTenuringChangedGroup);
154 7123 : }
155 :
156 : #ifdef DEBUG
157 : bool IsPretenureModeDependency() const override { return true; }
158 : #endif
159 :
160 : private:
161 : AllocationSiteRef site_;
162 : AllocationType allocation_;
163 : };
164 :
165 : class FieldTypeDependency final : public CompilationDependencies::Dependency {
166 : public:
167 : // TODO(neis): Once the concurrent compiler frontend is always-on, we no
168 : // longer need to explicitly store the type.
169 : FieldTypeDependency(const MapRef& owner, int descriptor,
170 : const ObjectRef& type)
171 4495 : : owner_(owner), descriptor_(descriptor), type_(type) {
172 : DCHECK(owner_.equals(owner_.FindFieldOwner(descriptor_)));
173 : DCHECK(type_.equals(owner_.GetFieldType(descriptor_)));
174 : }
175 :
176 8552 : bool IsValid() const override {
177 : DisallowHeapAllocation no_heap_allocation;
178 8552 : Handle<Map> owner = owner_.object();
179 8552 : Handle<Object> type = type_.object();
180 25656 : return *type == owner->instance_descriptors()->GetFieldType(descriptor_);
181 : }
182 :
183 4098 : void Install(const MaybeObjectHandle& code) override {
184 : SLOW_DCHECK(IsValid());
185 12294 : DependentCode::InstallDependency(owner_.isolate(), code, owner_.object(),
186 4098 : DependentCode::kFieldOwnerGroup);
187 4098 : }
188 :
189 : private:
190 : MapRef owner_;
191 : int descriptor_;
192 : ObjectRef type_;
193 : };
194 :
195 : class FieldConstnessDependency final
196 : : public CompilationDependencies::Dependency {
197 : public:
198 : FieldConstnessDependency(const MapRef& owner, int descriptor)
199 68882 : : owner_(owner), descriptor_(descriptor) {
200 : DCHECK(owner_.equals(owner_.FindFieldOwner(descriptor_)));
201 : DCHECK_EQ(PropertyConstness::kConst,
202 : owner_.GetPropertyDetails(descriptor_).constness());
203 : }
204 :
205 137093 : bool IsValid() const override {
206 : DisallowHeapAllocation no_heap_allocation;
207 137093 : Handle<Map> owner = owner_.object();
208 : return PropertyConstness::kConst ==
209 411279 : owner->instance_descriptors()->GetDetails(descriptor_).constness();
210 : }
211 :
212 68524 : void Install(const MaybeObjectHandle& code) override {
213 : SLOW_DCHECK(IsValid());
214 205572 : DependentCode::InstallDependency(owner_.isolate(), code, owner_.object(),
215 68524 : DependentCode::kFieldOwnerGroup);
216 68524 : }
217 :
218 : private:
219 : MapRef owner_;
220 : int descriptor_;
221 : };
222 :
223 : class GlobalPropertyDependency final
224 : : public CompilationDependencies::Dependency {
225 : public:
226 : // TODO(neis): Once the concurrent compiler frontend is always-on, we no
227 : // longer need to explicitly store the type and the read_only flag.
228 : GlobalPropertyDependency(const PropertyCellRef& cell, PropertyCellType type,
229 : bool read_only)
230 184208 : : cell_(cell), type_(type), read_only_(read_only) {
231 : DCHECK_EQ(type_, cell_.property_details().cell_type());
232 : DCHECK_EQ(read_only_, cell_.property_details().IsReadOnly());
233 : }
234 :
235 365782 : bool IsValid() const override {
236 365782 : Handle<PropertyCell> cell = cell_.object();
237 : // The dependency is never valid if the cell is 'invalidated'. This is
238 : // marked by setting the value to the hole.
239 731564 : if (cell->value() == *(cell_.isolate()->factory()->the_hole_value())) {
240 : DCHECK(cell->property_details().cell_type() ==
241 : PropertyCellType::kInvalidated ||
242 : cell->property_details().cell_type() ==
243 : PropertyCellType::kUninitialized);
244 : return false;
245 : }
246 1097318 : return type_ == cell->property_details().cell_type() &&
247 365770 : read_only_ == cell->property_details().IsReadOnly();
248 : }
249 :
250 182845 : void Install(const MaybeObjectHandle& code) override {
251 : SLOW_DCHECK(IsValid());
252 548535 : DependentCode::InstallDependency(cell_.isolate(), code, cell_.object(),
253 182845 : DependentCode::kPropertyCellChangedGroup);
254 182845 : }
255 :
256 : private:
257 : PropertyCellRef cell_;
258 : PropertyCellType type_;
259 : bool read_only_;
260 : };
261 :
262 : class ProtectorDependency final : public CompilationDependencies::Dependency {
263 : public:
264 19570 : explicit ProtectorDependency(const PropertyCellRef& cell) : cell_(cell) {
265 : DCHECK_EQ(cell_.value().AsSmi(), Isolate::kProtectorValid);
266 : }
267 :
268 38868 : bool IsValid() const override {
269 38868 : Handle<PropertyCell> cell = cell_.object();
270 38868 : return cell->value() == Smi::FromInt(Isolate::kProtectorValid);
271 : }
272 :
273 19432 : void Install(const MaybeObjectHandle& code) override {
274 : SLOW_DCHECK(IsValid());
275 58296 : DependentCode::InstallDependency(cell_.isolate(), code, cell_.object(),
276 19432 : DependentCode::kPropertyCellChangedGroup);
277 19432 : }
278 :
279 : private:
280 : PropertyCellRef cell_;
281 : };
282 :
283 : class ElementsKindDependency final
284 : : public CompilationDependencies::Dependency {
285 : public:
286 : // TODO(neis): Once the concurrent compiler frontend is always-on, we no
287 : // longer need to explicitly store the elements kind.
288 : ElementsKindDependency(const AllocationSiteRef& site, ElementsKind kind)
289 2884 : : site_(site), kind_(kind) {
290 : DCHECK(AllocationSite::ShouldTrack(kind_));
291 : DCHECK_EQ(kind_, site_.PointsToLiteral()
292 : ? site_.boilerplate().value().GetElementsKind()
293 : : site_.GetElementsKind());
294 : }
295 :
296 5691 : bool IsValid() const override {
297 5691 : Handle<AllocationSite> site = site_.object();
298 : ElementsKind kind = site->PointsToLiteral()
299 9461 : ? site->boilerplate()->GetElementsKind()
300 9461 : : site->GetElementsKind();
301 5691 : return kind_ == kind;
302 : }
303 :
304 2837 : void Install(const MaybeObjectHandle& code) override {
305 : SLOW_DCHECK(IsValid());
306 8511 : DependentCode::InstallDependency(
307 : site_.isolate(), code, site_.object(),
308 2837 : DependentCode::kAllocationSiteTransitionChangedGroup);
309 2837 : }
310 :
311 : private:
312 : AllocationSiteRef site_;
313 : ElementsKind kind_;
314 : };
315 :
316 : class InitialMapInstanceSizePredictionDependency final
317 : : public CompilationDependencies::Dependency {
318 : public:
319 : InitialMapInstanceSizePredictionDependency(const JSFunctionRef& function,
320 : int instance_size)
321 5058 : : function_(function), instance_size_(instance_size) {}
322 :
323 10059 : bool IsValid() const override {
324 : // The dependency is valid if the prediction is the same as the current
325 : // slack tracking result.
326 20118 : if (!function_.object()->has_initial_map()) return false;
327 30159 : int instance_size = function_.object()->ComputeInstanceSizeWithMinSlack(
328 10053 : function_.isolate());
329 10053 : return instance_size == instance_size_;
330 : }
331 :
332 5028 : void PrepareInstall() override {
333 : SLOW_DCHECK(IsValid());
334 10056 : function_.object()->CompleteInobjectSlackTrackingIfActive();
335 5028 : }
336 :
337 5025 : void Install(const MaybeObjectHandle& code) override {
338 : SLOW_DCHECK(IsValid());
339 : DCHECK(!function_.object()
340 : ->initial_map()
341 : ->IsInobjectSlackTrackingInProgress());
342 5025 : }
343 :
344 : private:
345 : JSFunctionRef function_;
346 : int instance_size_;
347 : };
348 :
349 5058 : MapRef CompilationDependencies::DependOnInitialMap(
350 : const JSFunctionRef& function) {
351 5058 : MapRef map = function.initial_map();
352 15174 : dependencies_.push_front(new (zone_) InitialMapDependency(function, map));
353 5058 : return map;
354 : }
355 :
356 1319 : ObjectRef CompilationDependencies::DependOnPrototypeProperty(
357 : const JSFunctionRef& function) {
358 1319 : ObjectRef prototype = function.prototype();
359 2638 : dependencies_.push_front(
360 1319 : new (zone_) PrototypePropertyDependency(function, prototype));
361 1319 : return prototype;
362 : }
363 :
364 160811 : void CompilationDependencies::DependOnStableMap(const MapRef& map) {
365 160811 : if (map.CanTransition()) {
366 476271 : dependencies_.push_front(new (zone_) StableMapDependency(map));
367 : } else {
368 : DCHECK(map.is_stable());
369 : }
370 160811 : }
371 :
372 21490 : void CompilationDependencies::DependOnTransition(const MapRef& target_map) {
373 21490 : if (target_map.CanBeDeprecated()) {
374 57306 : dependencies_.push_front(new (zone_) TransitionDependency(target_map));
375 : } else {
376 : DCHECK(!target_map.is_deprecated());
377 : }
378 21490 : }
379 :
380 7250 : AllocationType CompilationDependencies::DependOnPretenureMode(
381 : const AllocationSiteRef& site) {
382 7250 : AllocationType allocation = site.GetAllocationType();
383 21750 : dependencies_.push_front(new (zone_)
384 : PretenureModeDependency(site, allocation));
385 7250 : return allocation;
386 : }
387 :
388 68914 : PropertyConstness CompilationDependencies::DependOnFieldConstness(
389 : const MapRef& map, int descriptor) {
390 68914 : MapRef owner = map.FindFieldOwner(descriptor);
391 : PropertyConstness constness =
392 137828 : owner.GetPropertyDetails(descriptor).constness();
393 68914 : if (constness == PropertyConstness::kMutable) return constness;
394 :
395 : // If the map can have fast elements transitions, then the field can be only
396 : // considered constant if the map does not transition.
397 137764 : if (Map::CanHaveFastTransitionableElementsKind(map.instance_type())) {
398 : // If the map can already transition away, let us report the field as
399 : // mutable.
400 13079 : if (!map.is_stable()) {
401 : return PropertyConstness::kMutable;
402 : }
403 13079 : DependOnStableMap(map);
404 : }
405 :
406 : DCHECK_EQ(constness, PropertyConstness::kConst);
407 206646 : dependencies_.push_front(new (zone_)
408 : FieldConstnessDependency(owner, descriptor));
409 68882 : return PropertyConstness::kConst;
410 : }
411 :
412 4495 : void CompilationDependencies::DependOnFieldType(const MapRef& map,
413 : int descriptor) {
414 4495 : MapRef owner = map.FindFieldOwner(descriptor);
415 4495 : ObjectRef type = owner.GetFieldType(descriptor);
416 : DCHECK(type.equals(map.GetFieldType(descriptor)));
417 13485 : dependencies_.push_front(new (zone_)
418 : FieldTypeDependency(owner, descriptor, type));
419 4495 : }
420 :
421 184208 : void CompilationDependencies::DependOnGlobalProperty(
422 : const PropertyCellRef& cell) {
423 368416 : PropertyCellType type = cell.property_details().cell_type();
424 368416 : bool read_only = cell.property_details().IsReadOnly();
425 552624 : dependencies_.push_front(new (zone_)
426 : GlobalPropertyDependency(cell, type, read_only));
427 184208 : }
428 :
429 20489 : bool CompilationDependencies::DependOnProtector(const PropertyCellRef& cell) {
430 20489 : if (cell.value().AsSmi() != Isolate::kProtectorValid) return false;
431 58710 : dependencies_.push_front(new (zone_) ProtectorDependency(cell));
432 19570 : return true;
433 : }
434 :
435 8197 : bool CompilationDependencies::DependOnArrayBufferDetachingProtector() {
436 8197 : return DependOnProtector(PropertyCellRef(
437 : broker_,
438 24591 : broker_->isolate()->factory()->array_buffer_detaching_protector()));
439 : }
440 :
441 738 : bool CompilationDependencies::DependOnArrayIteratorProtector() {
442 738 : return DependOnProtector(PropertyCellRef(
443 2214 : broker_, broker_->isolate()->factory()->array_iterator_protector()));
444 : }
445 :
446 773 : bool CompilationDependencies::DependOnArraySpeciesProtector() {
447 773 : return DependOnProtector(PropertyCellRef(
448 2319 : broker_, broker_->isolate()->factory()->array_species_protector()));
449 : }
450 :
451 6411 : bool CompilationDependencies::DependOnNoElementsProtector() {
452 6411 : return DependOnProtector(PropertyCellRef(
453 19233 : broker_, broker_->isolate()->factory()->no_elements_protector()));
454 : }
455 :
456 3999 : bool CompilationDependencies::DependOnPromiseHookProtector() {
457 3999 : return DependOnProtector(PropertyCellRef(
458 11997 : broker_, broker_->isolate()->factory()->promise_hook_protector()));
459 : }
460 :
461 228 : bool CompilationDependencies::DependOnPromiseSpeciesProtector() {
462 228 : return DependOnProtector(PropertyCellRef(
463 684 : broker_, broker_->isolate()->factory()->promise_species_protector()));
464 : }
465 :
466 109 : bool CompilationDependencies::DependOnPromiseThenProtector() {
467 109 : return DependOnProtector(PropertyCellRef(
468 327 : broker_, broker_->isolate()->factory()->promise_then_protector()));
469 : }
470 :
471 7498 : void CompilationDependencies::DependOnElementsKind(
472 : const AllocationSiteRef& site) {
473 : // Do nothing if the object doesn't have any useful element transitions left.
474 7498 : ElementsKind kind = site.PointsToLiteral()
475 19542 : ? site.boilerplate().value().GetElementsKind()
476 14996 : : site.GetElementsKind();
477 7498 : if (AllocationSite::ShouldTrack(kind)) {
478 8652 : dependencies_.push_front(new (zone_) ElementsKindDependency(site, kind));
479 : }
480 7498 : }
481 :
482 372 : bool CompilationDependencies::AreValid() const {
483 688 : for (auto dep : dependencies_) {
484 396 : if (!dep->IsValid()) return false;
485 : }
486 : return true;
487 : }
488 :
489 463634 : bool CompilationDependencies::Commit(Handle<Code> code) {
490 937044 : for (auto dep : dependencies_) {
491 473463 : if (!dep->IsValid()) {
492 : dependencies_.clear();
493 : return false;
494 : }
495 473410 : dep->PrepareInstall();
496 : }
497 :
498 : DisallowCodeDependencyChange no_dependency_change;
499 936831 : for (auto dep : dependencies_) {
500 : // Check each dependency's validity again right before installing it,
501 : // because the first iteration above might have invalidated some
502 : // dependencies. For example, PrototypePropertyDependency::PrepareInstall
503 : // can call EnsureHasInitialMap, which can invalidate a StableMapDependency
504 : // on the prototype object's map.
505 473264 : if (!dep->IsValid()) {
506 : dependencies_.clear();
507 : return false;
508 : }
509 473250 : dep->Install(MaybeObjectHandle::Weak(code));
510 : }
511 :
512 : // It is even possible that a GC during the above installations invalidated
513 : // one of the dependencies. However, this should only affect pretenure mode
514 : // dependencies, which we assert below. It is safe to return successfully in
515 : // these cases, because once the code gets executed it will do a stack check
516 : // that triggers its deoptimization.
517 463567 : if (FLAG_stress_gc_during_compilation) {
518 2 : broker_->isolate()->heap()->PreciseCollectAllGarbage(
519 : Heap::kNoGCFlags, GarbageCollectionReason::kTesting,
520 2 : kGCCallbackFlagForced);
521 : }
522 : #ifdef DEBUG
523 : for (auto dep : dependencies_) {
524 : CHECK_IMPLIES(!dep->IsValid(), dep->IsPretenureModeDependency());
525 : }
526 : #endif
527 :
528 : dependencies_.clear();
529 463567 : return true;
530 : }
531 :
532 : namespace {
533 : // This function expects to never see a JSProxy.
534 53528 : void DependOnStablePrototypeChain(CompilationDependencies* deps, MapRef map,
535 : const JSObjectRef& last_prototype) {
536 29343 : while (true) {
537 82871 : map.SerializePrototype();
538 82871 : JSObjectRef proto = map.prototype().AsJSObject();
539 82871 : map = proto.map();
540 82871 : deps->DependOnStableMap(map);
541 82871 : if (proto.equals(last_prototype)) break;
542 : }
543 53528 : }
544 : } // namespace
545 :
546 51514 : void CompilationDependencies::DependOnStablePrototypeChains(
547 : std::vector<Handle<Map>> const& receiver_maps, const JSObjectRef& holder) {
548 : // Determine actual holder and perform prototype chain checks.
549 105042 : for (auto map : receiver_maps) {
550 53528 : MapRef receiver_map(broker_, map);
551 53528 : if (receiver_map.IsPrimitiveMap()) {
552 : // Perform the implicit ToObject for primitives here.
553 : // Implemented according to ES6 section 7.3.2 GetV (V, P).
554 : base::Optional<JSFunctionRef> constructor =
555 7882 : broker_->native_context().GetConstructorFunction(receiver_map);
556 7882 : if (constructor.has_value()) receiver_map = constructor->initial_map();
557 : }
558 53528 : DependOnStablePrototypeChain(this, receiver_map, holder);
559 : }
560 51514 : }
561 :
562 5774 : void CompilationDependencies::DependOnElementsKinds(
563 : const AllocationSiteRef& site) {
564 5774 : AllocationSiteRef current = site;
565 248 : while (true) {
566 6022 : DependOnElementsKind(current);
567 6022 : if (!current.nested_site().IsAllocationSite()) break;
568 248 : current = current.nested_site().AsAllocationSite();
569 : }
570 5774 : CHECK_EQ(current.nested_site().AsSmi(), 0);
571 5774 : }
572 :
573 968 : SlackTrackingPrediction::SlackTrackingPrediction(MapRef initial_map,
574 : int instance_size)
575 : : instance_size_(instance_size),
576 : inobject_property_count_(
577 12052 : (instance_size >> kTaggedSizeLog2) -
578 7962 : initial_map.GetInObjectPropertiesStartInWords()) {}
579 :
580 : SlackTrackingPrediction
581 5058 : CompilationDependencies::DependOnInitialMapInstanceSizePrediction(
582 : const JSFunctionRef& function) {
583 5058 : MapRef initial_map = DependOnInitialMap(function);
584 5058 : int instance_size = function.InitialMapInstanceSizeWithMinSlack();
585 : // Currently, we always install the prediction dependency. If this turns out
586 : // to be too expensive, we can only install the dependency if slack
587 : // tracking is active.
588 10116 : dependencies_.push_front(
589 5058 : new (zone_)
590 : InitialMapInstanceSizePredictionDependency(function, instance_size));
591 : DCHECK_LE(instance_size, function.initial_map().instance_size());
592 5058 : return SlackTrackingPrediction(initial_map, instance_size);
593 : }
594 :
595 : } // namespace compiler
596 : } // namespace internal
597 120216 : } // namespace v8
|