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/bytecode-graph-builder.h"
6 :
7 : #include "src/ast/ast.h"
8 : #include "src/ast/scopes.h"
9 : #include "src/compiler/access-builder.h"
10 : #include "src/compiler/compiler-source-position-table.h"
11 : #include "src/compiler/linkage.h"
12 : #include "src/compiler/operator-properties.h"
13 : #include "src/compiler/simplified-operator.h"
14 : #include "src/interpreter/bytecodes.h"
15 : #include "src/objects-inl.h"
16 : #include "src/objects/literal-objects.h"
17 :
18 : namespace v8 {
19 : namespace internal {
20 : namespace compiler {
21 :
22 : // The abstract execution environment simulates the content of the interpreter
23 : // register file. The environment performs SSA-renaming of all tracked nodes at
24 : // split and merge points in the control flow.
25 : class BytecodeGraphBuilder::Environment : public ZoneObject {
26 : public:
27 : Environment(BytecodeGraphBuilder* builder, int register_count,
28 : int parameter_count, Node* control_dependency, Node* context);
29 :
30 : // Specifies whether environment binding methods should attach frame state
31 : // inputs to nodes representing the value being bound. This is done because
32 : // the {OutputFrameStateCombine} is closely related to the binding method.
33 : enum FrameStateAttachmentMode { kAttachFrameState, kDontAttachFrameState };
34 :
35 : int parameter_count() const { return parameter_count_; }
36 : int register_count() const { return register_count_; }
37 :
38 : Node* LookupAccumulator() const;
39 : Node* LookupRegister(interpreter::Register the_register) const;
40 :
41 : void BindAccumulator(Node* node,
42 : FrameStateAttachmentMode mode = kDontAttachFrameState);
43 : void BindRegister(interpreter::Register the_register, Node* node,
44 : FrameStateAttachmentMode mode = kDontAttachFrameState);
45 : void BindRegistersToProjections(
46 : interpreter::Register first_reg, Node* node,
47 : FrameStateAttachmentMode mode = kDontAttachFrameState);
48 : void RecordAfterState(Node* node,
49 : FrameStateAttachmentMode mode = kDontAttachFrameState);
50 :
51 : // Effect dependency tracked by this environment.
52 : Node* GetEffectDependency() { return effect_dependency_; }
53 : void UpdateEffectDependency(Node* dependency) {
54 8996173 : effect_dependency_ = dependency;
55 : }
56 :
57 : // Preserve a checkpoint of the environment for the IR graph. Any
58 : // further mutation of the environment will not affect checkpoints.
59 : Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine,
60 : bool owner_has_exception,
61 : const BytecodeLivenessState* liveness);
62 :
63 : // Control dependency tracked by this environment.
64 : Node* GetControlDependency() const { return control_dependency_; }
65 : void UpdateControlDependency(Node* dependency) {
66 8430978 : control_dependency_ = dependency;
67 : }
68 :
69 : Node* Context() const { return context_; }
70 397373 : void SetContext(Node* new_context) { context_ = new_context; }
71 :
72 : Environment* Copy();
73 : void Merge(Environment* other);
74 :
75 : void PrepareForOsrEntry();
76 : void PrepareForLoop(const BytecodeLoopAssignments& assignments);
77 : void PrepareForLoopExit(Node* loop,
78 : const BytecodeLoopAssignments& assignments);
79 :
80 : private:
81 : explicit Environment(const Environment* copy);
82 :
83 : bool StateValuesRequireUpdate(Node** state_values, Node** values, int count);
84 : void UpdateStateValues(Node** state_values, Node** values, int count);
85 : Node* GetStateValuesFromCache(Node** values, int count,
86 : const BitVector* liveness, int liveness_offset);
87 :
88 : int RegisterToValuesIndex(interpreter::Register the_register) const;
89 :
90 2120701 : Zone* zone() const { return builder_->local_zone(); }
91 9672807 : Graph* graph() const { return builder_->graph(); }
92 9619003 : CommonOperatorBuilder* common() const { return builder_->common(); }
93 : BytecodeGraphBuilder* builder() const { return builder_; }
94 : const NodeVector* values() const { return &values_; }
95 : NodeVector* values() { return &values_; }
96 : int register_base() const { return register_base_; }
97 : int accumulator_base() const { return accumulator_base_; }
98 :
99 : BytecodeGraphBuilder* builder_;
100 : int register_count_;
101 : int parameter_count_;
102 : Node* context_;
103 : Node* control_dependency_;
104 : Node* effect_dependency_;
105 : NodeVector values_;
106 : Node* parameters_state_values_;
107 : int register_base_;
108 : int accumulator_base_;
109 : };
110 :
111 :
112 : // Issues:
113 : // - Scopes - intimately tied to AST. Need to eval what is needed.
114 : // - Need to resolve closure parameter treatment.
115 2041459 : BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder,
116 : int register_count,
117 : int parameter_count,
118 : Node* control_dependency,
119 1497722 : Node* context)
120 : : builder_(builder),
121 : register_count_(register_count),
122 : parameter_count_(parameter_count),
123 : context_(context),
124 : control_dependency_(control_dependency),
125 : effect_dependency_(control_dependency),
126 : values_(builder->local_zone()),
127 861732 : parameters_state_values_(nullptr) {
128 : // The layout of values_ is:
129 : //
130 : // [receiver] [parameters] [registers] [accumulator]
131 : //
132 : // parameter[0] is the receiver (this), parameters 1..N are the
133 : // parameters supplied to the method (arg0..argN-1). The accumulator
134 : // is stored separately.
135 :
136 : // Parameters including the receiver
137 1179727 : for (int i = 0; i < parameter_count; i++) {
138 748861 : const char* debug_name = (i == 0) ? "%this" : nullptr;
139 748861 : const Operator* op = common()->Parameter(i, debug_name);
140 1497722 : Node* parameter = builder->graph()->NewNode(op, graph()->start());
141 748861 : values()->push_back(parameter);
142 : }
143 :
144 : // Registers
145 861732 : register_base_ = static_cast<int>(values()->size());
146 430866 : Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
147 861732 : values()->insert(values()->end(), register_count, undefined_constant);
148 :
149 : // Accumulator
150 861732 : accumulator_base_ = static_cast<int>(values()->size());
151 430866 : values()->push_back(undefined_constant);
152 430866 : }
153 :
154 1060350 : BytecodeGraphBuilder::Environment::Environment(
155 1060350 : const BytecodeGraphBuilder::Environment* other)
156 : : builder_(other->builder_),
157 : register_count_(other->register_count_),
158 : parameter_count_(other->parameter_count_),
159 : context_(other->context_),
160 : control_dependency_(other->control_dependency_),
161 : effect_dependency_(other->effect_dependency_),
162 : values_(other->zone()),
163 : parameters_state_values_(other->parameters_state_values_),
164 : register_base_(other->register_base_),
165 2120700 : accumulator_base_(other->accumulator_base_) {
166 : values_ = other->values_;
167 1060352 : }
168 :
169 :
170 0 : int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
171 10388909 : interpreter::Register the_register) const {
172 10388909 : if (the_register.is_parameter()) {
173 952886 : return the_register.ToParameterIndex(parameter_count());
174 : } else {
175 9436023 : return the_register.index() + register_base();
176 : }
177 : }
178 :
179 6801533 : Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
180 13603066 : return values()->at(accumulator_base_);
181 : }
182 :
183 :
184 6086199 : Node* BytecodeGraphBuilder::Environment::LookupRegister(
185 151045 : interpreter::Register the_register) const {
186 6086199 : if (the_register.is_current_context()) {
187 44200 : return Context();
188 6041999 : } else if (the_register.is_function_closure()) {
189 89340 : return builder()->GetFunctionClosure();
190 5952657 : } else if (the_register.is_new_target()) {
191 17505 : return builder()->GetNewTarget();
192 : } else {
193 : int values_index = RegisterToValuesIndex(the_register);
194 11870302 : return values()->at(values_index);
195 : }
196 : }
197 :
198 8157753 : void BytecodeGraphBuilder::Environment::BindAccumulator(
199 3039231 : Node* node, FrameStateAttachmentMode mode) {
200 8157753 : if (mode == FrameStateAttachmentMode::kAttachFrameState) {
201 3039231 : builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(0));
202 : }
203 16315502 : values()->at(accumulator_base_) = node;
204 8157751 : }
205 :
206 4451605 : void BytecodeGraphBuilder::Environment::BindRegister(
207 : interpreter::Register the_register, Node* node,
208 58278 : FrameStateAttachmentMode mode) {
209 : int values_index = RegisterToValuesIndex(the_register);
210 4451604 : if (mode == FrameStateAttachmentMode::kAttachFrameState) {
211 : builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
212 116556 : accumulator_base_ - values_index));
213 : }
214 8903208 : values()->at(values_index) = node;
215 4451604 : }
216 :
217 2144 : void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
218 7931 : interpreter::Register first_reg, Node* node,
219 13718 : FrameStateAttachmentMode mode) {
220 : int values_index = RegisterToValuesIndex(first_reg);
221 2144 : if (mode == FrameStateAttachmentMode::kAttachFrameState) {
222 : builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
223 4288 : accumulator_base_ - values_index));
224 : }
225 21649 : for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
226 5787 : values()->at(values_index + i) =
227 17361 : builder()->NewNode(common()->Projection(i), node);
228 : }
229 2144 : }
230 :
231 661091 : void BytecodeGraphBuilder::Environment::RecordAfterState(
232 661091 : Node* node, FrameStateAttachmentMode mode) {
233 661091 : if (mode == FrameStateAttachmentMode::kAttachFrameState) {
234 661091 : builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore());
235 : }
236 661091 : }
237 :
238 1060351 : BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::Environment::Copy() {
239 1060350 : return new (zone()) Environment(this);
240 : }
241 :
242 :
243 768324 : void BytecodeGraphBuilder::Environment::Merge(
244 17153030 : BytecodeGraphBuilder::Environment* other) {
245 : // Create a merge of the control dependencies of both environments and update
246 : // the current environment's control dependency accordingly.
247 : Node* control = builder()->MergeControl(GetControlDependency(),
248 768324 : other->GetControlDependency());
249 : UpdateControlDependency(control);
250 :
251 : // Create a merge of the effect dependencies of both environments and update
252 : // the current environment's effect dependency accordingly.
253 : Node* effect = builder()->MergeEffect(GetEffectDependency(),
254 768324 : other->GetEffectDependency(), control);
255 : UpdateEffectDependency(effect);
256 :
257 : // Introduce Phi nodes for values that have differing input at merge points,
258 : // potentially extending an existing Phi node if possible.
259 1536648 : context_ = builder()->MergeValue(context_, other->context_, control);
260 31232766 : for (size_t i = 0; i < values_.size(); i++) {
261 60160557 : values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
262 : }
263 768325 : }
264 :
265 45902 : void BytecodeGraphBuilder::Environment::PrepareForLoop(
266 1749381 : const BytecodeLoopAssignments& assignments) {
267 : // Create a control node for the loop header.
268 45902 : Node* control = builder()->NewLoop();
269 :
270 : // Create a Phi for external effects.
271 45902 : Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
272 : UpdateEffectDependency(effect);
273 :
274 : // Create Phis for any values that may be updated by the end of the loop.
275 91804 : context_ = builder()->NewPhi(1, context_, control);
276 290176 : for (int i = 0; i < parameter_count(); i++) {
277 99186 : if (assignments.ContainsParameter(i)) {
278 359219 : values_[i] = builder()->NewPhi(1, values_[i], control);
279 : }
280 : }
281 1300604 : for (int i = 0; i < register_count(); i++) {
282 627351 : if (assignments.ContainsLocal(i)) {
283 275631 : int index = register_base() + i;
284 826893 : values_[index] = builder()->NewPhi(1, values_[index], control);
285 : }
286 : }
287 :
288 45902 : if (assignments.ContainsAccumulator()) {
289 45902 : values_[accumulator_base()] =
290 91804 : builder()->NewPhi(1, values_[accumulator_base()], control);
291 : }
292 :
293 : // Connect to the loop end.
294 : Node* terminate = builder()->graph()->NewNode(
295 183608 : builder()->common()->Terminate(), effect, control);
296 45902 : builder()->exit_controls_.push_back(terminate);
297 45902 : }
298 :
299 286460 : void BytecodeGraphBuilder::Environment::PrepareForOsrEntry() {
300 : DCHECK_EQ(IrOpcode::kLoop, GetControlDependency()->opcode());
301 : DCHECK_EQ(1, GetControlDependency()->InputCount());
302 :
303 5745 : Node* start = graph()->start();
304 :
305 : // Create a control node for the OSR entry point and update the current
306 : // environment's dependencies accordingly.
307 5745 : Node* entry = graph()->NewNode(common()->OsrLoopEntry(), start, start);
308 : UpdateControlDependency(entry);
309 : UpdateEffectDependency(entry);
310 :
311 : // Create OSR values for each environment value.
312 : SetContext(graph()->NewNode(
313 5745 : common()->OsrValue(Linkage::kOsrContextSpillSlotIndex), entry));
314 11490 : int size = static_cast<int>(values()->size());
315 53845 : for (int i = 0; i < size; i++) {
316 : int idx = i; // Indexing scheme follows {StandardFrame}, adapt accordingly.
317 48100 : if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount;
318 48100 : if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex;
319 144300 : values()->at(i) = graph()->NewNode(common()->OsrValue(idx), entry);
320 : }
321 :
322 5745 : BailoutId loop_id(builder_->bytecode_iterator().current_offset());
323 : Node* frame_state =
324 5745 : Checkpoint(loop_id, OutputFrameStateCombine::Ignore(), false, nullptr);
325 : Node* checkpoint =
326 5745 : graph()->NewNode(common()->Checkpoint(), frame_state, entry, entry);
327 : UpdateEffectDependency(checkpoint);
328 :
329 : // Create the OSR guard nodes.
330 5745 : const Operator* guard_op = common()->OsrGuard(OsrGuardType::kUninitialized);
331 : Node* effect = checkpoint;
332 53845 : for (int i = 0; i < size; i++) {
333 48100 : values()->at(i) = effect =
334 96200 : graph()->NewNode(guard_op, values()->at(i), effect, entry);
335 : }
336 : Node* context = effect = graph()->NewNode(guard_op, Context(), effect, entry);
337 : SetContext(context);
338 : UpdateEffectDependency(effect);
339 5745 : }
340 :
341 5340397 : bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
342 : Node** state_values, Node** values, int count) {
343 5340397 : if (*state_values == nullptr) {
344 : return true;
345 : }
346 : Node::Inputs inputs = (*state_values)->inputs();
347 5061578 : if (inputs.count() != count) return true;
348 10224148 : for (int i = 0; i < count; i++) {
349 10244790 : if (inputs[i] != values[i]) {
350 : return true;
351 : }
352 : }
353 : return false;
354 : }
355 :
356 180464 : void BytecodeGraphBuilder::Environment::PrepareForLoopExit(
357 14387778 : Node* loop, const BytecodeLoopAssignments& assignments) {
358 : DCHECK_EQ(loop->opcode(), IrOpcode::kLoop);
359 :
360 : Node* control = GetControlDependency();
361 :
362 : // Create the loop exit node.
363 180464 : Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop);
364 : UpdateControlDependency(loop_exit);
365 :
366 : // Rename the effect.
367 : Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(),
368 180464 : GetEffectDependency(), loop_exit);
369 : UpdateEffectDependency(effect_rename);
370 :
371 : // TODO(jarin) We should also rename context here. However, unconditional
372 : // renaming confuses global object and native context specialization.
373 : // We should only rename if the context is assigned in the loop.
374 :
375 : // Rename the environment values if they were assigned in the loop.
376 1097404 : for (int i = 0; i < parameter_count(); i++) {
377 368238 : if (assignments.ContainsParameter(i)) {
378 : Node* rename =
379 4425027 : graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit);
380 15650 : values_[i] = rename;
381 : }
382 : }
383 8541674 : for (int i = 0; i < register_count(); i++) {
384 4180605 : if (assignments.ContainsLocal(i)) {
385 : Node* rename = graph()->NewNode(common()->LoopExitValue(),
386 6002244 : values_[register_base() + i], loop_exit);
387 4001502 : values_[register_base() + i] = rename;
388 : }
389 : }
390 :
391 180464 : if (assignments.ContainsAccumulator()) {
392 : Node* rename = graph()->NewNode(common()->LoopExitValue(),
393 541392 : values_[accumulator_base()], loop_exit);
394 360928 : values_[accumulator_base()] = rename;
395 : }
396 180464 : }
397 :
398 5340397 : void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
399 : Node** values,
400 598919 : int count) {
401 5340397 : if (StateValuesRequireUpdate(state_values, values, count)) {
402 299460 : const Operator* op = common()->StateValues(count, SparseInputMask::Dense());
403 299459 : (*state_values) = graph()->NewNode(op, count, values);
404 : }
405 5340398 : }
406 :
407 0 : Node* BytecodeGraphBuilder::Environment::GetStateValuesFromCache(
408 : Node** values, int count, const BitVector* liveness, int liveness_offset) {
409 : return builder_->state_values_cache_.GetNodeForValues(
410 12482207 : values, static_cast<size_t>(count), liveness, liveness_offset);
411 : }
412 :
413 5941774 : Node* BytecodeGraphBuilder::Environment::Checkpoint(
414 : BailoutId bailout_id, OutputFrameStateCombine combine,
415 54774363 : bool owner_has_exception, const BytecodeLivenessState* liveness) {
416 5941774 : if (parameter_count() == register_count()) {
417 : // Re-use the state-value cache if the number of local registers happens
418 : // to match the parameter count.
419 : parameters_state_values_ = GetStateValuesFromCache(
420 601378 : &values()->at(0), parameter_count(), nullptr, 0);
421 : } else {
422 : UpdateStateValues(¶meters_state_values_, &values()->at(0),
423 5340396 : parameter_count());
424 : }
425 :
426 : Node* registers_state_values =
427 5941776 : GetStateValuesFromCache(&values()->at(register_base()), register_count(),
428 5941776 : liveness ? &liveness->bit_vector() : nullptr, 0);
429 :
430 11805330 : bool accumulator_is_live = !liveness || liveness->AccumulatorIsLive();
431 : Node* accumulator_state_values;
432 7245621 : if (parameter_count() == 1 && accumulator_is_live &&
433 3911550 : values()->at(accumulator_base()) == values()->at(0)) {
434 : // Re-use the parameter state values if there happens to only be one
435 : // parameter and the accumulator is live and holds that parameter's value.
436 2718 : accumulator_state_values = parameters_state_values_;
437 : } else {
438 : // Otherwise, use the state values cache to hopefully re-use local register
439 : // state values (if there is only one local register), or at the very least
440 : // re-use previous accumulator state values.
441 : accumulator_state_values = GetStateValuesFromCache(
442 5939053 : &values()->at(accumulator_base()), 1,
443 5939053 : liveness ? &liveness->bit_vector() : nullptr, register_count());
444 : }
445 :
446 : const Operator* op = common()->FrameState(
447 11883540 : bailout_id, combine, builder()->frame_state_function_info());
448 : Node* result = graph()->NewNode(
449 : op, parameters_state_values_, registers_state_values,
450 : accumulator_state_values, Context(), builder()->GetFunctionClosure(),
451 17825316 : builder()->graph()->start());
452 :
453 5941777 : return result;
454 : }
455 :
456 430866 : BytecodeGraphBuilder::BytecodeGraphBuilder(
457 : Zone* local_zone, Handle<SharedFunctionInfo> shared_info,
458 : Handle<FeedbackVector> feedback_vector, BailoutId osr_ast_id,
459 : JSGraph* jsgraph, float invocation_frequency,
460 : SourcePositionTable* source_positions, int inlining_id,
461 430866 : JSTypeHintLowering::Flags flags)
462 : : local_zone_(local_zone),
463 : jsgraph_(jsgraph),
464 : invocation_frequency_(invocation_frequency),
465 : bytecode_array_(handle(shared_info->bytecode_array())),
466 : exception_handler_table_(
467 : handle(HandlerTable::cast(bytecode_array()->handler_table()))),
468 : feedback_vector_(feedback_vector),
469 : type_hint_lowering_(jsgraph, feedback_vector, flags),
470 : frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
471 : FrameStateType::kInterpretedFunction,
472 : bytecode_array()->parameter_count(),
473 430866 : bytecode_array()->register_count(), shared_info)),
474 : bytecode_iterator_(nullptr),
475 : bytecode_analysis_(nullptr),
476 : environment_(nullptr),
477 : osr_ast_id_(osr_ast_id),
478 : merge_environments_(local_zone),
479 : exception_handlers_(local_zone),
480 : current_exception_handler_(0),
481 : input_buffer_size_(0),
482 : input_buffer_(nullptr),
483 : needs_eager_checkpoint_(true),
484 : exit_controls_(local_zone),
485 : state_values_cache_(jsgraph),
486 : source_positions_(source_positions),
487 3016062 : start_position_(shared_info->start_position(), inlining_id) {}
488 :
489 38045 : Node* BytecodeGraphBuilder::GetNewTarget() {
490 17505 : if (!new_target_.is_set()) {
491 : int params = bytecode_array()->parameter_count();
492 : int index = Linkage::GetJSCallNewTargetParamIndex(params);
493 10270 : const Operator* op = common()->Parameter(index, "%new.target");
494 10270 : Node* node = NewNode(op, graph()->start());
495 : new_target_.set(node);
496 : }
497 17505 : return new_target_.get();
498 : }
499 :
500 :
501 1292598 : Node* BytecodeGraphBuilder::GetFunctionContext() {
502 430866 : if (!function_context_.is_set()) {
503 : int params = bytecode_array()->parameter_count();
504 : int index = Linkage::GetJSCallContextParamIndex(params);
505 430866 : const Operator* op = common()->Parameter(index, "%context");
506 430866 : Node* node = NewNode(op, graph()->start());
507 : function_context_.set(node);
508 : }
509 430866 : return function_context_.get();
510 : }
511 :
512 :
513 7001969 : Node* BytecodeGraphBuilder::GetFunctionClosure() {
514 6143095 : if (!function_closure_.is_set()) {
515 : int index = Linkage::kJSCallClosureParamIndex;
516 429437 : const Operator* op = common()->Parameter(index, "%closure");
517 429437 : Node* node = NewNode(op, graph()->start());
518 : function_closure_.set(node);
519 : }
520 6143095 : return function_closure_.get();
521 : }
522 :
523 :
524 27910 : Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
525 : const Operator* op =
526 13955 : javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
527 : Node* native_context = NewNode(op);
528 27910 : Node* result = NewNode(javascript()->LoadContext(0, index, true));
529 13955 : NodeProperties::ReplaceContextInput(result, native_context);
530 13955 : return result;
531 : }
532 :
533 :
534 0 : VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
535 : FeedbackSlot slot;
536 2101216 : if (slot_id >= FeedbackVector::kReservedIndexCount) {
537 : slot = feedback_vector()->ToSlot(slot_id);
538 : }
539 0 : return VectorSlotPair(feedback_vector(), slot);
540 : }
541 :
542 3446928 : bool BytecodeGraphBuilder::CreateGraph(bool stack_check) {
543 430866 : SourcePositionTable::Scope pos_scope(source_positions_, start_position_);
544 :
545 : // Set up the basic structure of the graph. Outputs for {Start} are the formal
546 : // parameters (including the receiver) plus new target, number of arguments,
547 : // context and closure.
548 430866 : int actual_parameter_count = bytecode_array()->parameter_count() + 4;
549 430866 : graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
550 :
551 : Environment env(this, bytecode_array()->register_count(),
552 : bytecode_array()->parameter_count(), graph()->start(),
553 1292598 : GetFunctionContext());
554 : set_environment(&env);
555 :
556 430866 : VisitBytecodes(stack_check);
557 :
558 : // Finish the basic structure of the graph.
559 : DCHECK_NE(0u, exit_controls_.size());
560 861732 : int const input_count = static_cast<int>(exit_controls_.size());
561 : Node** const inputs = &exit_controls_.front();
562 1292598 : Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
563 : graph()->SetEnd(end);
564 :
565 430866 : return true;
566 : }
567 :
568 15011170 : void BytecodeGraphBuilder::PrepareEagerCheckpoint() {
569 3549676 : if (needs_eager_checkpoint()) {
570 : // Create an explicit checkpoint node for before the operation. This only
571 : // needs to happen if we aren't effect-dominated by a {Checkpoint} already.
572 : mark_as_needing_eager_checkpoint(false);
573 2865373 : Node* node = NewNode(common()->Checkpoint());
574 : DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
575 : DCHECK_EQ(IrOpcode::kDead,
576 : NodeProperties::GetFrameStateInput(node)->opcode());
577 2865374 : BailoutId bailout_id(bytecode_iterator().current_offset());
578 :
579 : const BytecodeLivenessState* liveness_before =
580 : bytecode_analysis()->GetInLivenessFor(
581 2865374 : bytecode_iterator().current_offset());
582 :
583 : Node* frame_state_before = environment()->Checkpoint(
584 2865373 : bailout_id, OutputFrameStateCombine::Ignore(), false, liveness_before);
585 2865375 : NodeProperties::ReplaceFrameStateInput(node, frame_state_before);
586 : #ifdef DEBUG
587 : } else {
588 : // In case we skipped checkpoint creation above, we must be able to find an
589 : // existing checkpoint that effect-dominates the nodes about to be created.
590 : // Starting a search from the current effect-dependency has to succeed.
591 : Node* effect = environment()->GetEffectDependency();
592 : while (effect->opcode() != IrOpcode::kCheckpoint) {
593 : DCHECK(effect->op()->HasProperty(Operator::kNoWrite));
594 : DCHECK_EQ(1, effect->op()->EffectInputCount());
595 : effect = NodeProperties::GetEffectInput(effect);
596 : }
597 : }
598 : #else
599 : }
600 : #endif // DEBUG
601 3549678 : }
602 :
603 3760744 : void BytecodeGraphBuilder::PrepareFrameState(Node* node,
604 12282642 : OutputFrameStateCombine combine) {
605 3760744 : if (OperatorProperties::HasFrameStateInput(node->op())) {
606 : // Add the frame state for after the operation. The node in question has
607 : // already been created and had a {Dead} frame state input up until now.
608 : DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
609 : DCHECK_EQ(IrOpcode::kDead,
610 : NodeProperties::GetFrameStateInput(node)->opcode());
611 3070661 : BailoutId bailout_id(bytecode_iterator().current_offset());
612 3070661 : bool has_exception = NodeProperties::IsExceptionalCall(node);
613 :
614 : const BytecodeLivenessState* liveness_after =
615 : bytecode_analysis()->GetOutLivenessFor(
616 6141320 : bytecode_iterator().current_offset());
617 :
618 : Node* frame_state_after = environment()->Checkpoint(
619 6141322 : bailout_id, combine, has_exception, liveness_after);
620 3070661 : NodeProperties::ReplaceFrameStateInput(node, frame_state_after);
621 : }
622 3760743 : }
623 :
624 15190954 : void BytecodeGraphBuilder::VisitBytecodes(bool stack_check) {
625 430866 : BytecodeAnalysis bytecode_analysis(bytecode_array(), local_zone(),
626 861732 : FLAG_analyze_environment_liveness);
627 430866 : bytecode_analysis.Analyze(osr_ast_id_);
628 : set_bytecode_analysis(&bytecode_analysis);
629 :
630 430866 : interpreter::BytecodeArrayIterator iterator(bytecode_array());
631 : set_bytecode_iterator(&iterator);
632 : SourcePositionTableIterator source_position_iterator(
633 430866 : bytecode_array()->SourcePositionTable());
634 :
635 430866 : if (FLAG_trace_environment_liveness) {
636 0 : OFStream of(stdout);
637 :
638 0 : bytecode_analysis.PrintLivenessTo(of);
639 : }
640 :
641 430866 : BuildOSRNormalEntryPoint();
642 :
643 14760090 : for (; !iterator.done(); iterator.Advance()) {
644 14329211 : int current_offset = iterator.current_offset();
645 14329211 : UpdateCurrentSourcePosition(&source_position_iterator, current_offset);
646 14329213 : EnterAndExitExceptionHandlers(current_offset);
647 14329225 : SwitchToMergeEnvironment(current_offset);
648 14329222 : if (environment() != nullptr) {
649 13759713 : BuildLoopHeaderEnvironment(current_offset);
650 :
651 : // Skip the first stack check if stack_check is false
652 13804356 : if (!stack_check &&
653 44642 : iterator.current_bytecode() == interpreter::Bytecode::kStackCheck) {
654 : stack_check = true;
655 : continue;
656 : }
657 :
658 13721686 : switch (iterator.current_bytecode()) {
659 : #define BYTECODE_CASE(name, ...) \
660 : case interpreter::Bytecode::k##name: \
661 : Visit##name(); \
662 : break;
663 864591 : BYTECODE_LIST(BYTECODE_CASE)
664 : #undef BYTECODE_CODE
665 : }
666 : }
667 : }
668 : set_bytecode_analysis(nullptr);
669 : set_bytecode_iterator(nullptr);
670 430866 : DCHECK(exception_handlers_.empty());
671 430866 : }
672 :
673 486224 : void BytecodeGraphBuilder::VisitLdaZero() {
674 243112 : Node* node = jsgraph()->ZeroConstant();
675 243112 : environment()->BindAccumulator(node);
676 243112 : }
677 :
678 3634872 : void BytecodeGraphBuilder::VisitLdaSmi() {
679 2423248 : Node* node = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
680 1211624 : environment()->BindAccumulator(node);
681 1211624 : }
682 :
683 1923414 : void BytecodeGraphBuilder::VisitLdaConstant() {
684 : Node* node =
685 1282276 : jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
686 641138 : environment()->BindAccumulator(node);
687 641138 : }
688 :
689 266334 : void BytecodeGraphBuilder::VisitLdaUndefined() {
690 133167 : Node* node = jsgraph()->UndefinedConstant();
691 133167 : environment()->BindAccumulator(node);
692 133167 : }
693 :
694 20402 : void BytecodeGraphBuilder::VisitLdaNull() {
695 10201 : Node* node = jsgraph()->NullConstant();
696 10201 : environment()->BindAccumulator(node);
697 10201 : }
698 :
699 223756 : void BytecodeGraphBuilder::VisitLdaTheHole() {
700 111878 : Node* node = jsgraph()->TheHoleConstant();
701 111878 : environment()->BindAccumulator(node);
702 111878 : }
703 :
704 76998 : void BytecodeGraphBuilder::VisitLdaTrue() {
705 38499 : Node* node = jsgraph()->TrueConstant();
706 38499 : environment()->BindAccumulator(node);
707 38499 : }
708 :
709 166390 : void BytecodeGraphBuilder::VisitLdaFalse() {
710 83195 : Node* node = jsgraph()->FalseConstant();
711 83195 : environment()->BindAccumulator(node);
712 83195 : }
713 :
714 2028303 : void BytecodeGraphBuilder::VisitLdar() {
715 : Node* value =
716 1352202 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
717 676101 : environment()->BindAccumulator(value);
718 676101 : }
719 :
720 11702029 : void BytecodeGraphBuilder::VisitStar() {
721 3900676 : Node* value = environment()->LookupAccumulator();
722 7801353 : environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value);
723 3900677 : }
724 :
725 1615264 : void BytecodeGraphBuilder::VisitMov() {
726 : Node* value =
727 807632 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
728 807632 : environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value);
729 403816 : }
730 :
731 528276 : Node* BytecodeGraphBuilder::BuildLoadGlobal(Handle<Name> name,
732 : uint32_t feedback_slot_index,
733 528276 : TypeofMode typeof_mode) {
734 1056552 : VectorSlotPair feedback = CreateVectorSlotPair(feedback_slot_index);
735 : DCHECK(IsLoadGlobalICKind(feedback_vector()->GetKind(feedback.slot())));
736 528276 : const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
737 528276 : return NewNode(op);
738 : }
739 :
740 1657667 : void BytecodeGraphBuilder::VisitLdaGlobal() {
741 414416 : PrepareEagerCheckpoint();
742 : Handle<Name> name =
743 414417 : Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
744 414417 : uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
745 : Node* node =
746 414417 : BuildLoadGlobal(name, feedback_slot_index, TypeofMode::NOT_INSIDE_TYPEOF);
747 414417 : environment()->BindAccumulator(node, Environment::kAttachFrameState);
748 414417 : }
749 :
750 1716 : void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
751 429 : PrepareEagerCheckpoint();
752 : Handle<Name> name =
753 429 : Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
754 429 : uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
755 : Node* node =
756 429 : BuildLoadGlobal(name, feedback_slot_index, TypeofMode::INSIDE_TYPEOF);
757 429 : environment()->BindAccumulator(node, Environment::kAttachFrameState);
758 429 : }
759 :
760 221568 : void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) {
761 36928 : PrepareEagerCheckpoint();
762 : Handle<Name> name =
763 36928 : Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
764 : VectorSlotPair feedback =
765 73856 : CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
766 36928 : Node* value = environment()->LookupAccumulator();
767 :
768 36928 : const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
769 : Node* node = NewNode(op, value);
770 36928 : environment()->RecordAfterState(node, Environment::kAttachFrameState);
771 36928 : }
772 :
773 0 : void BytecodeGraphBuilder::VisitStaGlobalSloppy() {
774 36339 : BuildStoreGlobal(LanguageMode::SLOPPY);
775 0 : }
776 :
777 0 : void BytecodeGraphBuilder::VisitStaGlobalStrict() {
778 589 : BuildStoreGlobal(LanguageMode::STRICT);
779 0 : }
780 :
781 486354 : void BytecodeGraphBuilder::VisitStaDataPropertyInLiteral() {
782 44214 : PrepareEagerCheckpoint();
783 :
784 : Node* object =
785 88428 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
786 : Node* name =
787 88428 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
788 44214 : Node* value = environment()->LookupAccumulator();
789 44214 : int flags = bytecode_iterator().GetFlagOperand(2);
790 : VectorSlotPair feedback =
791 88428 : CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(3));
792 :
793 44214 : const Operator* op = javascript()->StoreDataPropertyInLiteral(feedback);
794 44214 : Node* node = NewNode(op, object, name, value, jsgraph()->Constant(flags));
795 44214 : environment()->RecordAfterState(node, Environment::kAttachFrameState);
796 44214 : }
797 :
798 532 : void BytecodeGraphBuilder::VisitCollectTypeProfile() {
799 76 : PrepareEagerCheckpoint();
800 :
801 : Node* position =
802 152 : jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
803 76 : Node* value = environment()->LookupAccumulator();
804 76 : Node* vector = jsgraph()->Constant(feedback_vector());
805 :
806 76 : const Operator* op = javascript()->CallRuntime(Runtime::kCollectTypeProfile);
807 :
808 : Node* node = NewNode(op, position, value, vector);
809 76 : environment()->RecordAfterState(node, Environment::kAttachFrameState);
810 76 : }
811 :
812 86388 : void BytecodeGraphBuilder::VisitLdaContextSlot() {
813 : const Operator* op = javascript()->LoadContext(
814 14398 : bytecode_iterator().GetUnsignedImmediateOperand(2),
815 43194 : bytecode_iterator().GetIndexOperand(1), false);
816 : Node* node = NewNode(op);
817 : Node* context =
818 28796 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
819 14398 : NodeProperties::ReplaceContextInput(node, context);
820 14398 : environment()->BindAccumulator(node);
821 14398 : }
822 :
823 96888 : void BytecodeGraphBuilder::VisitLdaImmutableContextSlot() {
824 : const Operator* op = javascript()->LoadContext(
825 16148 : bytecode_iterator().GetUnsignedImmediateOperand(2),
826 48444 : bytecode_iterator().GetIndexOperand(1), true);
827 : Node* node = NewNode(op);
828 : Node* context =
829 32296 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
830 16148 : NodeProperties::ReplaceContextInput(node, context);
831 16148 : environment()->BindAccumulator(node);
832 16148 : }
833 :
834 633108 : void BytecodeGraphBuilder::VisitLdaCurrentContextSlot() {
835 : const Operator* op = javascript()->LoadContext(
836 422072 : 0, bytecode_iterator().GetIndexOperand(0), false);
837 : Node* node = NewNode(op);
838 211036 : environment()->BindAccumulator(node);
839 211036 : }
840 :
841 444030 : void BytecodeGraphBuilder::VisitLdaImmutableCurrentContextSlot() {
842 : const Operator* op = javascript()->LoadContext(
843 296020 : 0, bytecode_iterator().GetIndexOperand(0), true);
844 : Node* node = NewNode(op);
845 148010 : environment()->BindAccumulator(node);
846 148010 : }
847 :
848 25218 : void BytecodeGraphBuilder::VisitStaContextSlot() {
849 : const Operator* op = javascript()->StoreContext(
850 4203 : bytecode_iterator().GetUnsignedImmediateOperand(2),
851 12609 : bytecode_iterator().GetIndexOperand(1));
852 4203 : Node* value = environment()->LookupAccumulator();
853 : Node* node = NewNode(op, value);
854 : Node* context =
855 8406 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
856 4203 : NodeProperties::ReplaceContextInput(node, context);
857 4203 : }
858 :
859 460395 : void BytecodeGraphBuilder::VisitStaCurrentContextSlot() {
860 : const Operator* op =
861 306930 : javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(0));
862 153465 : Node* value = environment()->LookupAccumulator();
863 : NewNode(op, value);
864 153465 : }
865 :
866 13455 : void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) {
867 2691 : PrepareEagerCheckpoint();
868 : Node* name =
869 5382 : jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
870 : const Operator* op =
871 : javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
872 : ? Runtime::kLoadLookupSlot
873 5382 : : Runtime::kLoadLookupSlotInsideTypeof);
874 : Node* value = NewNode(op, name);
875 2691 : environment()->BindAccumulator(value, Environment::kAttachFrameState);
876 2691 : }
877 :
878 0 : void BytecodeGraphBuilder::VisitLdaLookupSlot() {
879 2673 : BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF);
880 0 : }
881 :
882 0 : void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() {
883 18 : BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF);
884 0 : }
885 :
886 114300 : BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions(
887 589730 : uint32_t depth) {
888 : // Output environment where the context has an extension
889 : Environment* slow_environment = nullptr;
890 :
891 : // We only need to check up to the last-but-one depth, because the an eval in
892 : // the same scope as the variable itself has no way of shadowing it.
893 232246 : for (uint32_t d = 0; d < depth; d++) {
894 : Node* extension_slot =
895 235892 : NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false));
896 :
897 : Node* check_no_extension =
898 : NewNode(simplified()->ReferenceEqual(), extension_slot,
899 235892 : jsgraph()->TheHoleConstant());
900 :
901 117946 : NewBranch(check_no_extension);
902 117946 : Environment* true_environment = environment()->Copy();
903 :
904 : {
905 117946 : NewIfFalse();
906 : // If there is an extension, merge into the slow path.
907 117946 : if (slow_environment == nullptr) {
908 : slow_environment = environment();
909 114201 : NewMerge();
910 : } else {
911 3745 : slow_environment->Merge(environment());
912 : }
913 : }
914 :
915 : {
916 : set_environment(true_environment);
917 117946 : NewIfTrue();
918 : // Do nothing on if there is no extension, eventually falling through to
919 : // the fast path.
920 : }
921 : }
922 :
923 : // The depth can be zero, in which case no slow-path checks are built, and the
924 : // slow path environment can be null.
925 : DCHECK(depth == 0 || slow_environment != nullptr);
926 :
927 114300 : return slow_environment;
928 : }
929 :
930 8658 : void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) {
931 870 : uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
932 :
933 : // Check if any context in the depth has an extension.
934 870 : Environment* slow_environment = CheckContextExtensions(depth);
935 :
936 : // Fast path, do a context load.
937 : {
938 870 : uint32_t slot_index = bytecode_iterator().GetIndexOperand(1);
939 :
940 1740 : const Operator* op = javascript()->LoadContext(depth, slot_index, false);
941 870 : environment()->BindAccumulator(NewNode(op));
942 : }
943 :
944 : // Only build the slow path if there were any slow-path checks.
945 870 : if (slow_environment != nullptr) {
946 : // Add a merge to the fast environment.
947 863 : NewMerge();
948 : Environment* fast_environment = environment();
949 :
950 : // Slow path, do a runtime load lookup.
951 : set_environment(slow_environment);
952 : {
953 : Node* name = jsgraph()->Constant(
954 1726 : bytecode_iterator().GetConstantForIndexOperand(0));
955 :
956 : const Operator* op =
957 : javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
958 : ? Runtime::kLoadLookupSlot
959 1726 : : Runtime::kLoadLookupSlotInsideTypeof);
960 : Node* value = NewNode(op, name);
961 863 : environment()->BindAccumulator(value, Environment::kAttachFrameState);
962 : }
963 :
964 863 : fast_environment->Merge(environment());
965 : set_environment(fast_environment);
966 : mark_as_needing_eager_checkpoint(true);
967 : }
968 870 : }
969 :
970 0 : void BytecodeGraphBuilder::VisitLdaLookupContextSlot() {
971 864 : BuildLdaLookupContextSlot(TypeofMode::NOT_INSIDE_TYPEOF);
972 0 : }
973 :
974 0 : void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() {
975 6 : BuildLdaLookupContextSlot(TypeofMode::INSIDE_TYPEOF);
976 0 : }
977 :
978 1133748 : void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) {
979 113430 : uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
980 :
981 : // Check if any context in the depth has an extension.
982 113430 : Environment* slow_environment = CheckContextExtensions(depth);
983 :
984 : // Fast path, do a global load.
985 : {
986 113430 : PrepareEagerCheckpoint();
987 : Handle<Name> name =
988 113430 : Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
989 113430 : uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
990 113430 : Node* node = BuildLoadGlobal(name, feedback_slot_index, typeof_mode);
991 113430 : environment()->BindAccumulator(node, Environment::kAttachFrameState);
992 : }
993 :
994 : // Only build the slow path if there were any slow-path checks.
995 113430 : if (slow_environment != nullptr) {
996 : // Add a merge to the fast environment.
997 113338 : NewMerge();
998 : Environment* fast_environment = environment();
999 :
1000 : // Slow path, do a runtime load lookup.
1001 : set_environment(slow_environment);
1002 : {
1003 : Node* name = jsgraph()->Constant(
1004 226676 : bytecode_iterator().GetConstantForIndexOperand(0));
1005 :
1006 : const Operator* op =
1007 : javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
1008 : ? Runtime::kLoadLookupSlot
1009 226676 : : Runtime::kLoadLookupSlotInsideTypeof);
1010 : Node* value = NewNode(op, name);
1011 113338 : environment()->BindAccumulator(value, Environment::kAttachFrameState);
1012 : }
1013 :
1014 113338 : fast_environment->Merge(environment());
1015 : set_environment(fast_environment);
1016 : mark_as_needing_eager_checkpoint(true);
1017 : }
1018 113430 : }
1019 :
1020 0 : void BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() {
1021 113355 : BuildLdaLookupGlobalSlot(TypeofMode::NOT_INSIDE_TYPEOF);
1022 0 : }
1023 :
1024 0 : void BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() {
1025 75 : BuildLdaLookupGlobalSlot(TypeofMode::INSIDE_TYPEOF);
1026 0 : }
1027 :
1028 66126 : void BytecodeGraphBuilder::BuildStaLookupSlot(LanguageMode language_mode) {
1029 11021 : PrepareEagerCheckpoint();
1030 11021 : Node* value = environment()->LookupAccumulator();
1031 : Node* name =
1032 22042 : jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
1033 : const Operator* op = javascript()->CallRuntime(
1034 : is_strict(language_mode) ? Runtime::kStoreLookupSlot_Strict
1035 22042 : : Runtime::kStoreLookupSlot_Sloppy);
1036 : Node* store = NewNode(op, name, value);
1037 11021 : environment()->BindAccumulator(store, Environment::kAttachFrameState);
1038 11021 : }
1039 :
1040 0 : void BytecodeGraphBuilder::VisitStaLookupSlotSloppy() {
1041 9218 : BuildStaLookupSlot(LanguageMode::SLOPPY);
1042 0 : }
1043 :
1044 0 : void BytecodeGraphBuilder::VisitStaLookupSlotStrict() {
1045 1803 : BuildStaLookupSlot(LanguageMode::STRICT);
1046 0 : }
1047 :
1048 3224824 : void BytecodeGraphBuilder::VisitLdaNamedProperty() {
1049 460689 : PrepareEagerCheckpoint();
1050 : Node* object =
1051 921378 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1052 : Handle<Name> name =
1053 460689 : Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
1054 : VectorSlotPair feedback =
1055 921378 : CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
1056 460689 : const Operator* op = javascript()->LoadNamed(name, feedback);
1057 :
1058 : Node* node = nullptr;
1059 460689 : if (Node* simplified =
1060 460689 : TryBuildSimplifiedLoadNamed(op, object, feedback.slot())) {
1061 45246 : if (environment() == nullptr) return;
1062 : node = simplified;
1063 : } else {
1064 : node = NewNode(op, object);
1065 : }
1066 :
1067 438067 : environment()->BindAccumulator(node, Environment::kAttachFrameState);
1068 : }
1069 :
1070 481761 : void BytecodeGraphBuilder::VisitLdaKeyedProperty() {
1071 68823 : PrepareEagerCheckpoint();
1072 68823 : Node* key = environment()->LookupAccumulator();
1073 : Node* object =
1074 137646 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1075 : VectorSlotPair feedback =
1076 137646 : CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
1077 68823 : const Operator* op = javascript()->LoadProperty(feedback);
1078 :
1079 : Node* node = nullptr;
1080 68823 : if (Node* simplified =
1081 68823 : TryBuildSimplifiedLoadKeyed(op, object, key, feedback.slot())) {
1082 696 : if (environment() == nullptr) return;
1083 : node = simplified;
1084 : } else {
1085 : node = NewNode(op, object, key);
1086 : }
1087 :
1088 68475 : environment()->BindAccumulator(node, Environment::kAttachFrameState);
1089 : }
1090 :
1091 98946 : void BytecodeGraphBuilder::BuildNamedStore(LanguageMode language_mode,
1092 692622 : StoreMode store_mode) {
1093 98946 : PrepareEagerCheckpoint();
1094 98946 : Node* value = environment()->LookupAccumulator();
1095 : Node* object =
1096 197892 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1097 : Handle<Name> name =
1098 98946 : Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
1099 : VectorSlotPair feedback =
1100 197892 : CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
1101 :
1102 : const Operator* op;
1103 98946 : if (store_mode == StoreMode::kOwn) {
1104 : DCHECK_EQ(FeedbackSlotKind::kStoreOwnNamed,
1105 : feedback.vector()->GetKind(feedback.slot()));
1106 34417 : op = javascript()->StoreNamedOwn(name, feedback);
1107 : } else {
1108 : DCHECK(store_mode == StoreMode::kNormal);
1109 : DCHECK_EQ(feedback.vector()->GetLanguageMode(feedback.slot()),
1110 : language_mode);
1111 64529 : op = javascript()->StoreNamed(language_mode, name, feedback);
1112 : }
1113 :
1114 : Node* node = nullptr;
1115 98946 : if (Node* simplified =
1116 98946 : TryBuildSimplifiedStoreNamed(op, object, value, feedback.slot())) {
1117 750 : if (environment() == nullptr) return;
1118 : node = simplified;
1119 : } else {
1120 : node = NewNode(op, object, value);
1121 : }
1122 :
1123 98571 : environment()->RecordAfterState(node, Environment::kAttachFrameState);
1124 : }
1125 :
1126 0 : void BytecodeGraphBuilder::VisitStaNamedPropertySloppy() {
1127 23177 : BuildNamedStore(LanguageMode::SLOPPY, StoreMode::kNormal);
1128 0 : }
1129 :
1130 0 : void BytecodeGraphBuilder::VisitStaNamedPropertyStrict() {
1131 41352 : BuildNamedStore(LanguageMode::STRICT, StoreMode::kNormal);
1132 0 : }
1133 :
1134 0 : void BytecodeGraphBuilder::VisitStaNamedOwnProperty() {
1135 34417 : BuildNamedStore(LanguageMode::STRICT, StoreMode::kOwn);
1136 0 : }
1137 :
1138 366300 : void BytecodeGraphBuilder::BuildKeyedStore(LanguageMode language_mode) {
1139 40700 : PrepareEagerCheckpoint();
1140 40700 : Node* value = environment()->LookupAccumulator();
1141 : Node* object =
1142 81400 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1143 : Node* key =
1144 81400 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1145 : VectorSlotPair feedback =
1146 81400 : CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
1147 : DCHECK_EQ(feedback.vector()->GetLanguageMode(feedback.slot()), language_mode);
1148 40700 : const Operator* op = javascript()->StoreProperty(language_mode, feedback);
1149 :
1150 : Node* node = nullptr;
1151 40700 : if (Node* simplified = TryBuildSimplifiedStoreKeyed(op, object, key, value,
1152 40700 : feedback.slot())) {
1153 138 : if (environment() == nullptr) return;
1154 : node = simplified;
1155 : } else {
1156 : node = NewNode(op, object, key, value);
1157 : }
1158 :
1159 40631 : environment()->RecordAfterState(node, Environment::kAttachFrameState);
1160 : }
1161 :
1162 0 : void BytecodeGraphBuilder::VisitStaKeyedPropertySloppy() {
1163 25089 : BuildKeyedStore(LanguageMode::SLOPPY);
1164 0 : }
1165 :
1166 0 : void BytecodeGraphBuilder::VisitStaKeyedPropertyStrict() {
1167 15611 : BuildKeyedStore(LanguageMode::STRICT);
1168 0 : }
1169 :
1170 2030 : void BytecodeGraphBuilder::VisitLdaModuleVariable() {
1171 406 : int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
1172 406 : uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
1173 : Node* module =
1174 812 : NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, true));
1175 406 : Node* value = NewNode(javascript()->LoadModule(cell_index), module);
1176 406 : environment()->BindAccumulator(value);
1177 406 : }
1178 :
1179 2430 : void BytecodeGraphBuilder::VisitStaModuleVariable() {
1180 486 : int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
1181 486 : uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
1182 : Node* module =
1183 972 : NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX, true));
1184 486 : Node* value = environment()->LookupAccumulator();
1185 486 : NewNode(javascript()->StoreModule(cell_index), module, value);
1186 486 : }
1187 :
1188 225496 : void BytecodeGraphBuilder::VisitPushContext() {
1189 56374 : Node* new_context = environment()->LookupAccumulator();
1190 : environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
1191 169122 : environment()->Context());
1192 : environment()->SetContext(new_context);
1193 56374 : }
1194 :
1195 123273 : void BytecodeGraphBuilder::VisitPopContext() {
1196 : Node* context =
1197 82182 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1198 : environment()->SetContext(context);
1199 41091 : }
1200 :
1201 920595 : void BytecodeGraphBuilder::VisitCreateClosure() {
1202 : Handle<SharedFunctionInfo> shared_info = Handle<SharedFunctionInfo>::cast(
1203 184119 : bytecode_iterator().GetConstantForIndexOperand(0));
1204 184119 : int const slot_id = bytecode_iterator().GetIndexOperand(1);
1205 184119 : VectorSlotPair pair = CreateVectorSlotPair(slot_id);
1206 : PretenureFlag tenured =
1207 : interpreter::CreateClosureFlags::PretenuredBit::decode(
1208 184119 : bytecode_iterator().GetFlagOperand(2))
1209 : ? TENURED
1210 184119 : : NOT_TENURED;
1211 184119 : const Operator* op = javascript()->CreateClosure(shared_info, pair, tenured);
1212 : Node* closure = NewNode(op);
1213 184119 : environment()->BindAccumulator(closure);
1214 184119 : }
1215 :
1216 26708 : void BytecodeGraphBuilder::VisitCreateBlockContext() {
1217 : Handle<ScopeInfo> scope_info = Handle<ScopeInfo>::cast(
1218 6677 : bytecode_iterator().GetConstantForIndexOperand(0));
1219 :
1220 6677 : const Operator* op = javascript()->CreateBlockContext(scope_info);
1221 6677 : Node* context = NewNode(op, environment()->LookupAccumulator());
1222 6677 : environment()->BindAccumulator(context);
1223 6677 : }
1224 :
1225 40254 : void BytecodeGraphBuilder::VisitCreateFunctionContext() {
1226 13418 : uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(0);
1227 : const Operator* op =
1228 26836 : javascript()->CreateFunctionContext(slots, FUNCTION_SCOPE);
1229 13418 : Node* context = NewNode(op, GetFunctionClosure());
1230 13418 : environment()->BindAccumulator(context);
1231 13418 : }
1232 :
1233 13152 : void BytecodeGraphBuilder::VisitCreateEvalContext() {
1234 4384 : uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(0);
1235 8768 : const Operator* op = javascript()->CreateFunctionContext(slots, EVAL_SCOPE);
1236 4384 : Node* context = NewNode(op, GetFunctionClosure());
1237 4384 : environment()->BindAccumulator(context);
1238 4384 : }
1239 :
1240 188146 : void BytecodeGraphBuilder::VisitCreateCatchContext() {
1241 26878 : interpreter::Register reg = bytecode_iterator().GetRegisterOperand(0);
1242 26878 : Node* exception = environment()->LookupRegister(reg);
1243 : Handle<String> name =
1244 26878 : Handle<String>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
1245 : Handle<ScopeInfo> scope_info = Handle<ScopeInfo>::cast(
1246 26878 : bytecode_iterator().GetConstantForIndexOperand(2));
1247 26878 : Node* closure = environment()->LookupAccumulator();
1248 :
1249 26878 : const Operator* op = javascript()->CreateCatchContext(name, scope_info);
1250 : Node* context = NewNode(op, exception, closure);
1251 26878 : environment()->BindAccumulator(context);
1252 26878 : }
1253 :
1254 5040 : void BytecodeGraphBuilder::VisitCreateWithContext() {
1255 : Node* object =
1256 1680 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1257 : Handle<ScopeInfo> scope_info = Handle<ScopeInfo>::cast(
1258 840 : bytecode_iterator().GetConstantForIndexOperand(1));
1259 :
1260 840 : const Operator* op = javascript()->CreateWithContext(scope_info);
1261 840 : Node* context = NewNode(op, object, environment()->LookupAccumulator());
1262 840 : environment()->BindAccumulator(context);
1263 840 : }
1264 :
1265 18860 : void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
1266 9430 : const Operator* op = javascript()->CreateArguments(type);
1267 9430 : Node* object = NewNode(op, GetFunctionClosure());
1268 9430 : environment()->BindAccumulator(object, Environment::kAttachFrameState);
1269 9430 : }
1270 :
1271 0 : void BytecodeGraphBuilder::VisitCreateMappedArguments() {
1272 5368 : BuildCreateArguments(CreateArgumentsType::kMappedArguments);
1273 0 : }
1274 :
1275 0 : void BytecodeGraphBuilder::VisitCreateUnmappedArguments() {
1276 3429 : BuildCreateArguments(CreateArgumentsType::kUnmappedArguments);
1277 0 : }
1278 :
1279 0 : void BytecodeGraphBuilder::VisitCreateRestParameter() {
1280 633 : BuildCreateArguments(CreateArgumentsType::kRestParameter);
1281 0 : }
1282 :
1283 50780 : void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
1284 : Handle<String> constant_pattern =
1285 10156 : Handle<String>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
1286 10156 : int literal_index = bytecode_iterator().GetIndexOperand(1);
1287 10156 : int literal_flags = bytecode_iterator().GetFlagOperand(2);
1288 : Node* literal = NewNode(javascript()->CreateLiteralRegExp(
1289 : constant_pattern, literal_flags, literal_index),
1290 20312 : GetFunctionClosure());
1291 10156 : environment()->BindAccumulator(literal, Environment::kAttachFrameState);
1292 10156 : }
1293 :
1294 128275 : void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
1295 : Handle<ConstantElementsPair> constant_elements =
1296 : Handle<ConstantElementsPair>::cast(
1297 25655 : bytecode_iterator().GetConstantForIndexOperand(0));
1298 25655 : int literal_index = bytecode_iterator().GetIndexOperand(1);
1299 25655 : int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
1300 : int literal_flags =
1301 : interpreter::CreateArrayLiteralFlags::FlagsBits::decode(bytecode_flags);
1302 : // Disable allocation site mementos. Only unoptimized code will collect
1303 : // feedback about allocation site. Once the code is optimized we expect the
1304 : // data to converge. So, we disable allocation site mementos in optimized
1305 : // code. We can revisit this when we have data to the contrary.
1306 25655 : literal_flags |= ArrayLiteral::kDisableMementos;
1307 : // TODO(mstarzinger): Thread through number of elements. The below number is
1308 : // only an estimate and does not match {ArrayLiteral::values::length}.
1309 : int number_of_elements = constant_elements->constant_values()->length();
1310 : Node* literal = NewNode(
1311 : javascript()->CreateLiteralArray(constant_elements, literal_flags,
1312 : literal_index, number_of_elements),
1313 51310 : GetFunctionClosure());
1314 25655 : environment()->BindAccumulator(literal, Environment::kAttachFrameState);
1315 25655 : }
1316 :
1317 293646 : void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
1318 : Handle<BoilerplateDescription> constant_properties =
1319 : Handle<BoilerplateDescription>::cast(
1320 48941 : bytecode_iterator().GetConstantForIndexOperand(0));
1321 48941 : int literal_index = bytecode_iterator().GetIndexOperand(1);
1322 48941 : int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
1323 : int literal_flags =
1324 : interpreter::CreateObjectLiteralFlags::FlagsBits::decode(bytecode_flags);
1325 : // TODO(mstarzinger): Thread through number of properties. The below number is
1326 : // only an estimate and does not match {ObjectLiteral::properties_count}.
1327 48941 : int number_of_properties = constant_properties->size();
1328 : Node* literal = NewNode(
1329 : javascript()->CreateLiteralObject(constant_properties, literal_flags,
1330 : literal_index, number_of_properties),
1331 97882 : GetFunctionClosure());
1332 : environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3),
1333 97882 : literal, Environment::kAttachFrameState);
1334 48941 : }
1335 :
1336 67368 : Node* const* BytecodeGraphBuilder::GetCallArgumentsFromRegister(
1337 : Node* callee, Node* receiver, interpreter::Register first_arg,
1338 806076 : int arg_count) {
1339 : // The arity of the Call node -- includes the callee, receiver and function
1340 : // arguments.
1341 67368 : int arity = 2 + arg_count;
1342 :
1343 67368 : Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
1344 :
1345 67368 : all[0] = callee;
1346 67368 : all[1] = receiver;
1347 :
1348 : // The function arguments are in consecutive registers.
1349 : int arg_base = first_arg.index();
1350 806076 : for (int i = 0; i < arg_count; ++i) {
1351 738708 : all[2 + i] =
1352 1477416 : environment()->LookupRegister(interpreter::Register(arg_base + i));
1353 : }
1354 :
1355 67368 : return all;
1356 : }
1357 :
1358 0 : Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
1359 : Node* const* args,
1360 : int arg_count) {
1361 618604 : return MakeNode(call_op, arg_count, args, false);
1362 : }
1363 :
1364 14197 : Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
1365 : Node* callee,
1366 : interpreter::Register receiver,
1367 14197 : size_t reg_count) {
1368 14197 : Node* receiver_node = environment()->LookupRegister(receiver);
1369 : // The receiver is followed by the arguments in the consecutive registers.
1370 : DCHECK_GE(reg_count, 1);
1371 14197 : interpreter::Register first_arg = interpreter::Register(receiver.index() + 1);
1372 14197 : int arg_count = static_cast<int>(reg_count) - 1;
1373 :
1374 : Node* const* call_args =
1375 14197 : GetCallArgumentsFromRegister(callee, receiver_node, first_arg, arg_count);
1376 28394 : return ProcessCallArguments(call_op, call_args, 2 + arg_count);
1377 : }
1378 :
1379 604407 : void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode,
1380 : ConvertReceiverMode receiver_mode,
1381 : Node* const* args, size_t arg_count,
1382 1208814 : int slot_id) {
1383 : DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
1384 : bytecode_iterator().current_bytecode()),
1385 : receiver_mode);
1386 604407 : PrepareEagerCheckpoint();
1387 :
1388 : // Slot index of 0 is used indicate no feedback slot is available. Assert
1389 : // the assumption that slot index 0 is never a valid feedback slot.
1390 : STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0);
1391 604407 : VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
1392 :
1393 604407 : float const frequency = ComputeCallFrequency(slot_id);
1394 : const Operator* call = javascript()->Call(arg_count, frequency, feedback,
1395 604407 : receiver_mode, tail_call_mode);
1396 604407 : Node* value = ProcessCallArguments(call, args, static_cast<int>(arg_count));
1397 604407 : environment()->BindAccumulator(value, Environment::kAttachFrameState);
1398 604407 : }
1399 :
1400 53171 : void BytecodeGraphBuilder::BuildCallVarArgs(TailCallMode tail_call_mode,
1401 319026 : ConvertReceiverMode receiver_mode) {
1402 : DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
1403 : bytecode_iterator().current_bytecode()),
1404 : receiver_mode);
1405 : Node* callee =
1406 106342 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1407 53171 : interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
1408 53171 : size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1409 53171 : int const slot_id = bytecode_iterator().GetIndexOperand(3);
1410 :
1411 : Node* receiver_node;
1412 : interpreter::Register first_arg;
1413 : int arg_count;
1414 :
1415 53171 : if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
1416 : // The receiver is implicit (and undefined), the arguments are in
1417 : // consecutive registers.
1418 40032 : receiver_node = jsgraph()->UndefinedConstant();
1419 40032 : first_arg = first_reg;
1420 40032 : arg_count = static_cast<int>(reg_count);
1421 : } else {
1422 : // The receiver is the first register, followed by the arguments in the
1423 : // consecutive registers.
1424 : DCHECK_GE(reg_count, 1);
1425 13139 : receiver_node = environment()->LookupRegister(first_reg);
1426 13139 : first_arg = interpreter::Register(first_reg.index() + 1);
1427 13139 : arg_count = static_cast<int>(reg_count) - 1;
1428 : }
1429 :
1430 : Node* const* call_args =
1431 53171 : GetCallArgumentsFromRegister(callee, receiver_node, first_arg, arg_count);
1432 : BuildCall(tail_call_mode, receiver_mode, call_args,
1433 53171 : static_cast<size_t>(2 + arg_count), slot_id);
1434 53171 : }
1435 :
1436 0 : void BytecodeGraphBuilder::VisitCallAnyReceiver() {
1437 800 : BuildCallVarArgs(TailCallMode::kDisallow, ConvertReceiverMode::kAny);
1438 0 : }
1439 :
1440 0 : void BytecodeGraphBuilder::VisitCallProperty() {
1441 : BuildCallVarArgs(TailCallMode::kDisallow,
1442 11405 : ConvertReceiverMode::kNotNullOrUndefined);
1443 0 : }
1444 :
1445 236580 : void BytecodeGraphBuilder::VisitCallProperty0() {
1446 : Node* callee =
1447 94632 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1448 : Node* receiver =
1449 94632 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1450 47316 : int const slot_id = bytecode_iterator().GetIndexOperand(2);
1451 : BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined,
1452 94632 : {callee, receiver}, slot_id);
1453 47316 : }
1454 :
1455 909867 : void BytecodeGraphBuilder::VisitCallProperty1() {
1456 : Node* callee =
1457 259962 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1458 : Node* receiver =
1459 259962 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1460 : Node* arg0 =
1461 259962 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
1462 129981 : int const slot_id = bytecode_iterator().GetIndexOperand(3);
1463 : BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined,
1464 259962 : {callee, receiver, arg0}, slot_id);
1465 129981 : }
1466 :
1467 189027 : void BytecodeGraphBuilder::VisitCallProperty2() {
1468 : Node* callee =
1469 42006 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1470 : Node* receiver =
1471 42006 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1472 : Node* arg0 =
1473 42006 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
1474 : Node* arg1 =
1475 42006 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3));
1476 21003 : int const slot_id = bytecode_iterator().GetIndexOperand(4);
1477 : BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNotNullOrUndefined,
1478 42006 : {callee, receiver, arg0, arg1}, slot_id);
1479 21003 : }
1480 :
1481 0 : void BytecodeGraphBuilder::VisitCallUndefinedReceiver() {
1482 : BuildCallVarArgs(TailCallMode::kDisallow,
1483 40032 : ConvertReceiverMode::kNullOrUndefined);
1484 0 : }
1485 :
1486 143412 : void BytecodeGraphBuilder::VisitCallUndefinedReceiver0() {
1487 : Node* callee =
1488 71706 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1489 35853 : Node* receiver = jsgraph()->UndefinedConstant();
1490 35853 : int const slot_id = bytecode_iterator().GetIndexOperand(1);
1491 : BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNullOrUndefined,
1492 71706 : {callee, receiver}, slot_id);
1493 35853 : }
1494 :
1495 1171278 : void BytecodeGraphBuilder::VisitCallUndefinedReceiver1() {
1496 : Node* callee =
1497 390426 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1498 195213 : Node* receiver = jsgraph()->UndefinedConstant();
1499 : Node* arg0 =
1500 390426 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1501 195213 : int const slot_id = bytecode_iterator().GetIndexOperand(2);
1502 : BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNullOrUndefined,
1503 390426 : {callee, receiver, arg0}, slot_id);
1504 195213 : }
1505 :
1506 974960 : void BytecodeGraphBuilder::VisitCallUndefinedReceiver2() {
1507 : Node* callee =
1508 243740 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1509 121870 : Node* receiver = jsgraph()->UndefinedConstant();
1510 : Node* arg0 =
1511 243740 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1512 : Node* arg1 =
1513 243740 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
1514 121870 : int const slot_id = bytecode_iterator().GetIndexOperand(3);
1515 : BuildCall(TailCallMode::kDisallow, ConvertReceiverMode::kNullOrUndefined,
1516 243740 : {callee, receiver, arg0, arg1}, slot_id);
1517 121870 : }
1518 :
1519 1694 : void BytecodeGraphBuilder::VisitCallWithSpread() {
1520 242 : PrepareEagerCheckpoint();
1521 : Node* callee =
1522 484 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1523 242 : interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1524 242 : size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1525 : const Operator* call =
1526 484 : javascript()->CallWithSpread(static_cast<int>(reg_count + 1));
1527 :
1528 242 : Node* value = ProcessCallArguments(call, callee, receiver, reg_count);
1529 242 : environment()->BindAccumulator(value, Environment::kAttachFrameState);
1530 242 : }
1531 :
1532 934 : void BytecodeGraphBuilder::VisitTailCall() {
1533 : TailCallMode tail_call_mode =
1534 934 : bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled()
1535 : ? TailCallMode::kAllow
1536 934 : : TailCallMode::kDisallow;
1537 934 : BuildCallVarArgs(tail_call_mode, ConvertReceiverMode::kAny);
1538 934 : }
1539 :
1540 83730 : void BytecodeGraphBuilder::VisitCallJSRuntime() {
1541 13955 : PrepareEagerCheckpoint();
1542 : Node* callee =
1543 13955 : BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0));
1544 13955 : interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1545 13955 : size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1546 :
1547 : // Create node to perform the JS runtime call.
1548 27910 : const Operator* call = javascript()->Call(reg_count + 1);
1549 13955 : Node* value = ProcessCallArguments(call, callee, receiver, reg_count);
1550 13955 : environment()->BindAccumulator(value, Environment::kAttachFrameState);
1551 13955 : }
1552 :
1553 259803 : Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
1554 : const Operator* call_runtime_op, interpreter::Register receiver,
1555 774582 : size_t reg_count) {
1556 259803 : int arg_count = static_cast<int>(reg_count);
1557 : // arity is args.
1558 : int arity = arg_count;
1559 259803 : Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
1560 : int first_arg_index = receiver.index();
1561 774582 : for (int i = 0; i < static_cast<int>(reg_count); ++i) {
1562 514779 : all[i] = environment()->LookupRegister(
1563 1029558 : interpreter::Register(first_arg_index + i));
1564 : }
1565 259803 : Node* value = MakeNode(call_runtime_op, arity, all, false);
1566 259803 : return value;
1567 : }
1568 :
1569 1225212 : void BytecodeGraphBuilder::VisitCallRuntime() {
1570 204202 : PrepareEagerCheckpoint();
1571 204202 : Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
1572 204202 : interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1573 204202 : size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1574 :
1575 : // Create node to perform the runtime call.
1576 204202 : const Operator* call = javascript()->CallRuntime(functionId, reg_count);
1577 204202 : Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
1578 204202 : environment()->BindAccumulator(value, Environment::kAttachFrameState);
1579 204202 : }
1580 :
1581 4515 : void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
1582 645 : PrepareEagerCheckpoint();
1583 645 : Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
1584 645 : interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1585 645 : size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1586 : interpreter::Register first_return =
1587 645 : bytecode_iterator().GetRegisterOperand(3);
1588 :
1589 : // Create node to perform the runtime call.
1590 645 : const Operator* call = javascript()->CallRuntime(functionId, reg_count);
1591 645 : Node* return_pair = ProcessCallRuntimeArguments(call, receiver, reg_count);
1592 : environment()->BindRegistersToProjections(first_return, return_pair,
1593 645 : Environment::kAttachFrameState);
1594 645 : }
1595 :
1596 247 : Node* BytecodeGraphBuilder::ProcessConstructWithSpreadArguments(
1597 : const Operator* op, Node* callee, Node* new_target,
1598 510 : interpreter::Register receiver, size_t reg_count) {
1599 247 : int arg_count = static_cast<int>(reg_count);
1600 : // arity is args + callee and new target.
1601 247 : int arity = arg_count + 2;
1602 247 : Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
1603 247 : all[0] = callee;
1604 : int first_arg_index = receiver.index();
1605 510 : for (int i = 0; i < arg_count; ++i) {
1606 263 : all[1 + i] = environment()->LookupRegister(
1607 526 : interpreter::Register(first_arg_index + i));
1608 : }
1609 247 : all[arity - 1] = new_target;
1610 247 : Node* value = MakeNode(op, arity, all, false);
1611 247 : return value;
1612 : }
1613 :
1614 1729 : void BytecodeGraphBuilder::VisitConstructWithSpread() {
1615 247 : PrepareEagerCheckpoint();
1616 247 : interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
1617 247 : interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1618 247 : size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1619 :
1620 247 : Node* new_target = environment()->LookupAccumulator();
1621 247 : Node* callee = environment()->LookupRegister(callee_reg);
1622 :
1623 : const Operator* op =
1624 494 : javascript()->ConstructWithSpread(static_cast<uint32_t>(reg_count + 2));
1625 : Node* value = ProcessConstructWithSpreadArguments(op, callee, new_target,
1626 247 : receiver, reg_count);
1627 247 : environment()->BindAccumulator(value, Environment::kAttachFrameState);
1628 247 : }
1629 :
1630 329736 : void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
1631 54956 : PrepareEagerCheckpoint();
1632 54956 : Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0);
1633 54956 : interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1634 54956 : size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1635 :
1636 : // Create node to perform the runtime call. Turbofan will take care of the
1637 : // lowering.
1638 54956 : const Operator* call = javascript()->CallRuntime(functionId, reg_count);
1639 54956 : Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
1640 54956 : environment()->BindAccumulator(value, Environment::kAttachFrameState);
1641 54956 : }
1642 :
1643 34114 : Node* BytecodeGraphBuilder::ProcessConstructArguments(
1644 : const Operator* call_new_op, Node* callee, Node* new_target,
1645 338900 : interpreter::Register receiver, size_t reg_count) {
1646 34114 : int arg_count = static_cast<int>(reg_count);
1647 : // arity is args + callee and new target.
1648 34114 : int arity = arg_count + 2;
1649 34114 : Node** all = local_zone()->NewArray<Node*>(static_cast<size_t>(arity));
1650 34114 : all[0] = callee;
1651 : int first_arg_index = receiver.index();
1652 338900 : for (int i = 0; i < arg_count; ++i) {
1653 304786 : all[1 + i] = environment()->LookupRegister(
1654 609572 : interpreter::Register(first_arg_index + i));
1655 : }
1656 34114 : all[arity - 1] = new_target;
1657 34114 : Node* value = MakeNode(call_new_op, arity, all, false);
1658 34114 : return value;
1659 : }
1660 :
1661 272912 : void BytecodeGraphBuilder::VisitConstruct() {
1662 34114 : PrepareEagerCheckpoint();
1663 34114 : interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
1664 34114 : interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1665 34114 : size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1666 : // Slot index of 0 is used indicate no feedback slot is available. Assert
1667 : // the assumption that slot index 0 is never a valid feedback slot.
1668 : STATIC_ASSERT(FeedbackVector::kReservedIndexCount > 0);
1669 34114 : int const slot_id = bytecode_iterator().GetIndexOperand(3);
1670 34114 : VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
1671 :
1672 34114 : Node* new_target = environment()->LookupAccumulator();
1673 34114 : Node* callee = environment()->LookupRegister(callee_reg);
1674 :
1675 34114 : float const frequency = ComputeCallFrequency(slot_id);
1676 : const Operator* call = javascript()->Construct(
1677 68228 : static_cast<uint32_t>(reg_count + 2), frequency, feedback);
1678 : Node* value =
1679 34114 : ProcessConstructArguments(call, callee, new_target, receiver, reg_count);
1680 34114 : environment()->BindAccumulator(value, Environment::kAttachFrameState);
1681 34114 : }
1682 :
1683 108755 : void BytecodeGraphBuilder::VisitThrow() {
1684 : BuildLoopExitsForFunctionExit();
1685 21751 : Node* value = environment()->LookupAccumulator();
1686 21751 : Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
1687 21751 : environment()->BindAccumulator(call, Environment::kAttachFrameState);
1688 21751 : Node* control = NewNode(common()->Throw());
1689 : MergeControlToLeaveFunction(control);
1690 21751 : }
1691 :
1692 45976 : void BytecodeGraphBuilder::VisitReThrow() {
1693 : BuildLoopExitsForFunctionExit();
1694 11494 : Node* value = environment()->LookupAccumulator();
1695 11494 : NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
1696 11494 : Node* control = NewNode(common()->Throw());
1697 : MergeControlToLeaveFunction(control);
1698 11494 : }
1699 :
1700 1575786 : void BytecodeGraphBuilder::BuildBinaryOp(const Operator* op) {
1701 262631 : PrepareEagerCheckpoint();
1702 : Node* left =
1703 525262 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1704 262631 : Node* right = environment()->LookupAccumulator();
1705 :
1706 : Node* node = nullptr;
1707 : FeedbackSlot slot = feedback_vector()->ToSlot(
1708 525262 : bytecode_iterator().GetIndexOperand(kBinaryOperationHintIndex));
1709 262631 : if (Node* simplified = TryBuildSimplifiedBinaryOp(op, left, right, slot)) {
1710 : node = simplified;
1711 : } else {
1712 : node = NewNode(op, left, right);
1713 : }
1714 :
1715 262631 : environment()->BindAccumulator(node, Environment::kAttachFrameState);
1716 262631 : }
1717 :
1718 : // Helper function to create binary operation hint from the recorded type
1719 : // feedback.
1720 264497 : BinaryOperationHint BytecodeGraphBuilder::GetBinaryOperationHint(
1721 264497 : int operand_index) {
1722 : FeedbackSlot slot = feedback_vector()->ToSlot(
1723 264497 : bytecode_iterator().GetIndexOperand(operand_index));
1724 : DCHECK_EQ(FeedbackSlotKind::kBinaryOp, feedback_vector()->GetKind(slot));
1725 : BinaryOpICNexus nexus(feedback_vector(), slot);
1726 264497 : return nexus.GetBinaryOperationFeedback();
1727 : }
1728 :
1729 : // Helper function to create compare operation hint from the recorded type
1730 : // feedback.
1731 709980 : CompareOperationHint BytecodeGraphBuilder::GetCompareOperationHint() {
1732 354990 : int slot_index = bytecode_iterator().GetIndexOperand(1);
1733 354990 : if (slot_index == 0) {
1734 : return CompareOperationHint::kAny;
1735 : }
1736 : FeedbackSlot slot =
1737 354990 : feedback_vector()->ToSlot(bytecode_iterator().GetIndexOperand(1));
1738 : DCHECK_EQ(FeedbackSlotKind::kCompareOp, feedback_vector()->GetKind(slot));
1739 : CompareICNexus nexus(feedback_vector(), slot);
1740 354990 : return nexus.GetCompareOperationFeedback();
1741 : }
1742 :
1743 638521 : float BytecodeGraphBuilder::ComputeCallFrequency(int slot_id) const {
1744 : CallICNexus nexus(feedback_vector(), feedback_vector()->ToSlot(slot_id));
1745 638521 : return nexus.ComputeCallFrequency() * invocation_frequency_;
1746 : }
1747 :
1748 391272 : void BytecodeGraphBuilder::VisitAdd() {
1749 : BuildBinaryOp(
1750 391272 : javascript()->Add(GetBinaryOperationHint(kBinaryOperationHintIndex)));
1751 195636 : }
1752 :
1753 7490 : void BytecodeGraphBuilder::VisitSub() {
1754 7490 : BuildBinaryOp(javascript()->Subtract());
1755 7490 : }
1756 :
1757 7366 : void BytecodeGraphBuilder::VisitMul() {
1758 7366 : BuildBinaryOp(javascript()->Multiply());
1759 7366 : }
1760 :
1761 65064 : void BytecodeGraphBuilder::VisitDiv() { BuildBinaryOp(javascript()->Divide()); }
1762 :
1763 1797 : void BytecodeGraphBuilder::VisitMod() {
1764 1797 : BuildBinaryOp(javascript()->Modulus());
1765 1797 : }
1766 :
1767 3406 : void BytecodeGraphBuilder::VisitBitwiseOr() {
1768 3406 : BuildBinaryOp(javascript()->BitwiseOr());
1769 3406 : }
1770 :
1771 5257 : void BytecodeGraphBuilder::VisitBitwiseXor() {
1772 5257 : BuildBinaryOp(javascript()->BitwiseXor());
1773 5257 : }
1774 :
1775 3608 : void BytecodeGraphBuilder::VisitBitwiseAnd() {
1776 3608 : BuildBinaryOp(javascript()->BitwiseAnd());
1777 3608 : }
1778 :
1779 2097 : void BytecodeGraphBuilder::VisitShiftLeft() {
1780 2097 : BuildBinaryOp(javascript()->ShiftLeft());
1781 2097 : }
1782 :
1783 1564 : void BytecodeGraphBuilder::VisitShiftRight() {
1784 1564 : BuildBinaryOp(javascript()->ShiftRight());
1785 1564 : }
1786 :
1787 1878 : void BytecodeGraphBuilder::VisitShiftRightLogical() {
1788 1878 : BuildBinaryOp(javascript()->ShiftRightLogical());
1789 1878 : }
1790 :
1791 1081302 : void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(const Operator* op) {
1792 180217 : PrepareEagerCheckpoint();
1793 180217 : Node* left = environment()->LookupAccumulator();
1794 360434 : Node* right = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
1795 :
1796 : Node* node = nullptr;
1797 : FeedbackSlot slot = feedback_vector()->ToSlot(
1798 360434 : bytecode_iterator().GetIndexOperand(kBinaryOperationSmiHintIndex));
1799 180217 : if (Node* simplified = TryBuildSimplifiedBinaryOp(op, left, right, slot)) {
1800 : node = simplified;
1801 : } else {
1802 : node = NewNode(op, left, right);
1803 : }
1804 :
1805 180217 : environment()->BindAccumulator(node, Environment::kAttachFrameState);
1806 180217 : }
1807 :
1808 137722 : void BytecodeGraphBuilder::VisitAddSmi() {
1809 : BuildBinaryOpWithImmediate(
1810 137722 : javascript()->Add(GetBinaryOperationHint(kBinaryOperationSmiHintIndex)));
1811 68861 : }
1812 :
1813 8039 : void BytecodeGraphBuilder::VisitSubSmi() {
1814 8039 : BuildBinaryOpWithImmediate(javascript()->Subtract());
1815 8039 : }
1816 :
1817 42807 : void BytecodeGraphBuilder::VisitMulSmi() {
1818 42807 : BuildBinaryOpWithImmediate(javascript()->Multiply());
1819 42807 : }
1820 :
1821 7459 : void BytecodeGraphBuilder::VisitDivSmi() {
1822 7459 : BuildBinaryOpWithImmediate(javascript()->Divide());
1823 7459 : }
1824 :
1825 4284 : void BytecodeGraphBuilder::VisitModSmi() {
1826 4284 : BuildBinaryOpWithImmediate(javascript()->Modulus());
1827 4284 : }
1828 :
1829 25227 : void BytecodeGraphBuilder::VisitBitwiseOrSmi() {
1830 25227 : BuildBinaryOpWithImmediate(javascript()->BitwiseOr());
1831 25227 : }
1832 :
1833 1517 : void BytecodeGraphBuilder::VisitBitwiseXorSmi() {
1834 1517 : BuildBinaryOpWithImmediate(javascript()->BitwiseXor());
1835 1517 : }
1836 :
1837 6281 : void BytecodeGraphBuilder::VisitBitwiseAndSmi() {
1838 6281 : BuildBinaryOpWithImmediate(javascript()->BitwiseAnd());
1839 6281 : }
1840 :
1841 4411 : void BytecodeGraphBuilder::VisitShiftLeftSmi() {
1842 4411 : BuildBinaryOpWithImmediate(javascript()->ShiftLeft());
1843 4411 : }
1844 :
1845 6299 : void BytecodeGraphBuilder::VisitShiftRightSmi() {
1846 6299 : BuildBinaryOpWithImmediate(javascript()->ShiftRight());
1847 6299 : }
1848 :
1849 5032 : void BytecodeGraphBuilder::VisitShiftRightLogicalSmi() {
1850 5032 : BuildBinaryOpWithImmediate(javascript()->ShiftRightLogical());
1851 5032 : }
1852 :
1853 224040 : void BytecodeGraphBuilder::VisitInc() {
1854 37340 : PrepareEagerCheckpoint();
1855 : // Note: Use subtract -1 here instead of add 1 to ensure we always convert to
1856 : // a number, not a string.
1857 37340 : Node* left = environment()->LookupAccumulator();
1858 37340 : Node* right = jsgraph()->Constant(-1);
1859 37340 : const Operator* op = javascript()->Subtract();
1860 :
1861 : Node* node = nullptr;
1862 : FeedbackSlot slot = feedback_vector()->ToSlot(
1863 74680 : bytecode_iterator().GetIndexOperand(kCountOperationHintIndex));
1864 37340 : if (Node* simplified = TryBuildSimplifiedBinaryOp(op, left, right, slot)) {
1865 : node = simplified;
1866 : } else {
1867 : node = NewNode(op, left, right);
1868 : }
1869 :
1870 37340 : environment()->BindAccumulator(node, Environment::kAttachFrameState);
1871 37340 : }
1872 :
1873 31422 : void BytecodeGraphBuilder::VisitDec() {
1874 5237 : PrepareEagerCheckpoint();
1875 5237 : Node* left = environment()->LookupAccumulator();
1876 5237 : Node* right = jsgraph()->OneConstant();
1877 5237 : const Operator* op = javascript()->Subtract();
1878 :
1879 : Node* node = nullptr;
1880 : FeedbackSlot slot = feedback_vector()->ToSlot(
1881 10474 : bytecode_iterator().GetIndexOperand(kCountOperationHintIndex));
1882 5237 : if (Node* simplified = TryBuildSimplifiedBinaryOp(op, left, right, slot)) {
1883 : node = simplified;
1884 : } else {
1885 : node = NewNode(op, left, right);
1886 : }
1887 :
1888 5237 : environment()->BindAccumulator(node, Environment::kAttachFrameState);
1889 5237 : }
1890 :
1891 14202 : void BytecodeGraphBuilder::VisitLogicalNot() {
1892 4734 : Node* value = environment()->LookupAccumulator();
1893 4734 : Node* node = NewNode(simplified()->BooleanNot(), value);
1894 4734 : environment()->BindAccumulator(node);
1895 4734 : }
1896 :
1897 34696 : void BytecodeGraphBuilder::VisitToBooleanLogicalNot() {
1898 : Node* value = NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
1899 26022 : environment()->LookupAccumulator());
1900 8674 : Node* node = NewNode(simplified()->BooleanNot(), value);
1901 8674 : environment()->BindAccumulator(node);
1902 8674 : }
1903 :
1904 93924 : void BytecodeGraphBuilder::VisitTypeOf() {
1905 : Node* node =
1906 62616 : NewNode(javascript()->TypeOf(), environment()->LookupAccumulator());
1907 31308 : environment()->BindAccumulator(node);
1908 31308 : }
1909 :
1910 11802 : void BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
1911 1686 : PrepareEagerCheckpoint();
1912 1686 : Node* key = environment()->LookupAccumulator();
1913 : Node* object =
1914 3372 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1915 3372 : Node* mode = jsgraph()->Constant(static_cast<int32_t>(language_mode));
1916 1686 : Node* node = NewNode(javascript()->DeleteProperty(), object, key, mode);
1917 1686 : environment()->BindAccumulator(node, Environment::kAttachFrameState);
1918 1686 : }
1919 :
1920 0 : void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
1921 888 : BuildDelete(LanguageMode::STRICT);
1922 0 : }
1923 :
1924 0 : void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
1925 798 : BuildDelete(LanguageMode::SLOPPY);
1926 0 : }
1927 :
1928 1860 : void BytecodeGraphBuilder::VisitGetSuperConstructor() {
1929 : Node* node = NewNode(javascript()->GetSuperConstructor(),
1930 930 : environment()->LookupAccumulator());
1931 : environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), node,
1932 930 : Environment::kAttachFrameState);
1933 465 : }
1934 :
1935 2129940 : void BytecodeGraphBuilder::BuildCompareOp(const Operator* op) {
1936 354990 : PrepareEagerCheckpoint();
1937 : Node* left =
1938 709980 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1939 354990 : Node* right = environment()->LookupAccumulator();
1940 :
1941 354990 : int slot_index = bytecode_iterator().GetIndexOperand(1);
1942 : DCHECK(slot_index != 0);
1943 354990 : FeedbackSlot slot = feedback_vector()->ToSlot(slot_index);
1944 : Node* node = nullptr;
1945 354990 : if (Node* simplified = TryBuildSimplifiedBinaryOp(op, left, right, slot)) {
1946 : node = simplified;
1947 : } else {
1948 : node = NewNode(op, left, right);
1949 : }
1950 354990 : environment()->BindAccumulator(node, Environment::kAttachFrameState);
1951 354990 : }
1952 :
1953 44140 : void BytecodeGraphBuilder::VisitTestEqual() {
1954 44140 : BuildCompareOp(javascript()->Equal(GetCompareOperationHint()));
1955 22070 : }
1956 :
1957 508452 : void BytecodeGraphBuilder::VisitTestEqualStrict() {
1958 508452 : BuildCompareOp(javascript()->StrictEqual(GetCompareOperationHint()));
1959 254226 : }
1960 :
1961 64916 : void BytecodeGraphBuilder::VisitTestLessThan() {
1962 64916 : BuildCompareOp(javascript()->LessThan(GetCompareOperationHint()));
1963 32458 : }
1964 :
1965 78204 : void BytecodeGraphBuilder::VisitTestGreaterThan() {
1966 78204 : BuildCompareOp(javascript()->GreaterThan(GetCompareOperationHint()));
1967 39102 : }
1968 :
1969 5370 : void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
1970 5370 : BuildCompareOp(javascript()->LessThanOrEqual(GetCompareOperationHint()));
1971 2685 : }
1972 :
1973 8898 : void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
1974 8898 : BuildCompareOp(javascript()->GreaterThanOrEqual(GetCompareOperationHint()));
1975 4449 : }
1976 :
1977 257730 : void BytecodeGraphBuilder::VisitTestEqualStrictNoFeedback() {
1978 : // TODO(5310): Currently this is used with both Smi operands and with
1979 : // string operands. We pass string operands for static property check in
1980 : // VisitClassLiteralProperties. This should be changed, so we only use this
1981 : // for Smi operations and lower it to SpeculativeNumberEqual[kSignedSmall]
1982 42955 : PrepareEagerCheckpoint();
1983 : Node* left =
1984 85910 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1985 42955 : Node* right = environment()->LookupAccumulator();
1986 :
1987 : Node* node = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
1988 42955 : left, right);
1989 42955 : environment()->BindAccumulator(node, Environment::kAttachFrameState);
1990 42955 : }
1991 :
1992 27175 : void BytecodeGraphBuilder::BuildTestingOp(const Operator* op) {
1993 5435 : PrepareEagerCheckpoint();
1994 : Node* left =
1995 10870 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1996 5435 : Node* right = environment()->LookupAccumulator();
1997 : Node* node = NewNode(op, left, right);
1998 5435 : environment()->BindAccumulator(node, Environment::kAttachFrameState);
1999 5435 : }
2000 :
2001 3362 : void BytecodeGraphBuilder::VisitTestIn() {
2002 3362 : BuildTestingOp(javascript()->HasProperty());
2003 3362 : }
2004 :
2005 2073 : void BytecodeGraphBuilder::VisitTestInstanceOf() {
2006 2073 : BuildTestingOp(javascript()->InstanceOf());
2007 2073 : }
2008 :
2009 23889 : void BytecodeGraphBuilder::VisitTestUndetectable() {
2010 7963 : Node* object = environment()->LookupAccumulator();
2011 7963 : Node* node = NewNode(jsgraph()->simplified()->ObjectIsUndetectable(), object);
2012 7963 : environment()->BindAccumulator(node);
2013 7963 : }
2014 :
2015 588 : void BytecodeGraphBuilder::VisitTestNull() {
2016 147 : Node* object = environment()->LookupAccumulator();
2017 : Node* result = NewNode(simplified()->ReferenceEqual(), object,
2018 294 : jsgraph()->NullConstant());
2019 147 : environment()->BindAccumulator(result);
2020 147 : }
2021 :
2022 5912 : void BytecodeGraphBuilder::VisitTestUndefined() {
2023 1478 : Node* object = environment()->LookupAccumulator();
2024 : Node* result = NewNode(simplified()->ReferenceEqual(), object,
2025 2956 : jsgraph()->UndefinedConstant());
2026 1478 : environment()->BindAccumulator(result);
2027 1478 : }
2028 :
2029 366228 : void BytecodeGraphBuilder::VisitTestTypeOf() {
2030 59510 : Node* object = environment()->LookupAccumulator();
2031 : auto literal_flag = interpreter::TestTypeOfFlags::Decode(
2032 59510 : bytecode_iterator().GetFlagOperand(0));
2033 : Node* result;
2034 59510 : switch (literal_flag) {
2035 : case interpreter::TestTypeOfFlags::LiteralFlag::kNumber:
2036 16151 : result = NewNode(simplified()->ObjectIsNumber(), object);
2037 16151 : break;
2038 : case interpreter::TestTypeOfFlags::LiteralFlag::kString:
2039 4816 : result = NewNode(simplified()->ObjectIsString(), object);
2040 4816 : break;
2041 : case interpreter::TestTypeOfFlags::LiteralFlag::kSymbol:
2042 663 : result = NewNode(simplified()->ObjectIsSymbol(), object);
2043 663 : break;
2044 : case interpreter::TestTypeOfFlags::LiteralFlag::kBoolean:
2045 : result = NewNode(common()->Select(MachineRepresentation::kTagged),
2046 : NewNode(simplified()->ReferenceEqual(), object,
2047 : jsgraph()->TrueConstant()),
2048 : jsgraph()->TrueConstant(),
2049 : NewNode(simplified()->ReferenceEqual(), object,
2050 2784 : jsgraph()->FalseConstant()));
2051 464 : break;
2052 : case interpreter::TestTypeOfFlags::LiteralFlag::kUndefined:
2053 : result = graph()->NewNode(
2054 : common()->Select(MachineRepresentation::kTagged),
2055 : graph()->NewNode(simplified()->ReferenceEqual(), object,
2056 : jsgraph()->NullConstant()),
2057 : jsgraph()->FalseConstant(),
2058 8150 : graph()->NewNode(simplified()->ObjectIsUndetectable(), object));
2059 1630 : break;
2060 : case interpreter::TestTypeOfFlags::LiteralFlag::kFunction:
2061 : result =
2062 22674 : graph()->NewNode(simplified()->ObjectIsDetectableCallable(), object);
2063 22674 : break;
2064 : case interpreter::TestTypeOfFlags::LiteralFlag::kObject:
2065 : result = graph()->NewNode(
2066 : common()->Select(MachineRepresentation::kTagged),
2067 : graph()->NewNode(simplified()->ObjectIsNonCallable(), object),
2068 : jsgraph()->TrueConstant(),
2069 : graph()->NewNode(simplified()->ReferenceEqual(), object,
2070 65560 : jsgraph()->NullConstant()));
2071 13112 : break;
2072 : case interpreter::TestTypeOfFlags::LiteralFlag::kOther:
2073 0 : UNREACHABLE(); // Should never be emitted.
2074 : result = nullptr;
2075 : break;
2076 : }
2077 59510 : environment()->BindAccumulator(result);
2078 59510 : }
2079 :
2080 11637 : void BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
2081 3879 : Node* value = NewNode(js_op, environment()->LookupAccumulator());
2082 : environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value,
2083 7758 : Environment::kAttachFrameState);
2084 3879 : }
2085 :
2086 1540 : void BytecodeGraphBuilder::VisitToName() {
2087 1540 : BuildCastOperator(javascript()->ToName());
2088 1540 : }
2089 :
2090 2339 : void BytecodeGraphBuilder::VisitToObject() {
2091 2339 : BuildCastOperator(javascript()->ToObject());
2092 2339 : }
2093 :
2094 27739 : void BytecodeGraphBuilder::VisitToNumber() {
2095 4993 : PrepareEagerCheckpoint();
2096 4993 : Node* object = environment()->LookupAccumulator();
2097 :
2098 : Node* node = nullptr;
2099 : FeedbackSlot slot =
2100 9986 : feedback_vector()->ToSlot(bytecode_iterator().GetIndexOperand(1));
2101 4993 : if (Node* simplified = TryBuildSimplifiedToNumber(object, slot)) {
2102 : node = simplified;
2103 : } else {
2104 2774 : node = NewNode(javascript()->ToNumber(), object);
2105 : }
2106 :
2107 : environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), node,
2108 9986 : Environment::kAttachFrameState);
2109 4993 : }
2110 :
2111 129540 : void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
2112 :
2113 10382 : void BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
2114 :
2115 193252 : void BytecodeGraphBuilder::VisitJumpIfTrue() { BuildJumpIfTrue(); }
2116 :
2117 7093 : void BytecodeGraphBuilder::VisitJumpIfTrueConstant() { BuildJumpIfTrue(); }
2118 :
2119 246181 : void BytecodeGraphBuilder::VisitJumpIfFalse() { BuildJumpIfFalse(); }
2120 :
2121 3271 : void BytecodeGraphBuilder::VisitJumpIfFalseConstant() { BuildJumpIfFalse(); }
2122 :
2123 0 : void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
2124 38027 : BuildJumpIfToBooleanTrue();
2125 0 : }
2126 :
2127 0 : void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
2128 1909 : BuildJumpIfToBooleanTrue();
2129 0 : }
2130 :
2131 0 : void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
2132 66300 : BuildJumpIfToBooleanFalse();
2133 0 : }
2134 :
2135 0 : void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
2136 214 : BuildJumpIfToBooleanFalse();
2137 0 : }
2138 :
2139 17384 : void BytecodeGraphBuilder::VisitJumpIfNotHole() { BuildJumpIfNotHole(); }
2140 :
2141 0 : void BytecodeGraphBuilder::VisitJumpIfNotHoleConstant() {
2142 0 : BuildJumpIfNotHole();
2143 0 : }
2144 :
2145 6291 : void BytecodeGraphBuilder::VisitJumpIfJSReceiver() { BuildJumpIfJSReceiver(); }
2146 :
2147 0 : void BytecodeGraphBuilder::VisitJumpIfJSReceiverConstant() {
2148 0 : BuildJumpIfJSReceiver();
2149 0 : }
2150 :
2151 2697 : void BytecodeGraphBuilder::VisitJumpIfNull() {
2152 2697 : BuildJumpIfEqual(jsgraph()->NullConstant());
2153 2697 : }
2154 :
2155 72 : void BytecodeGraphBuilder::VisitJumpIfNullConstant() {
2156 72 : BuildJumpIfEqual(jsgraph()->NullConstant());
2157 72 : }
2158 :
2159 2441 : void BytecodeGraphBuilder::VisitJumpIfNotNull() {
2160 2441 : BuildJumpIfNotEqual(jsgraph()->NullConstant());
2161 2441 : }
2162 :
2163 0 : void BytecodeGraphBuilder::VisitJumpIfNotNullConstant() {
2164 0 : BuildJumpIfNotEqual(jsgraph()->NullConstant());
2165 0 : }
2166 :
2167 11082 : void BytecodeGraphBuilder::VisitJumpIfUndefined() {
2168 11082 : BuildJumpIfEqual(jsgraph()->UndefinedConstant());
2169 11082 : }
2170 :
2171 171 : void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
2172 171 : BuildJumpIfEqual(jsgraph()->UndefinedConstant());
2173 171 : }
2174 :
2175 5948 : void BytecodeGraphBuilder::VisitJumpIfNotUndefined() {
2176 5948 : BuildJumpIfNotEqual(jsgraph()->UndefinedConstant());
2177 5948 : }
2178 :
2179 8 : void BytecodeGraphBuilder::VisitJumpIfNotUndefinedConstant() {
2180 8 : BuildJumpIfNotEqual(jsgraph()->UndefinedConstant());
2181 8 : }
2182 :
2183 44415 : void BytecodeGraphBuilder::VisitJumpLoop() { BuildJump(); }
2184 :
2185 1318898 : void BytecodeGraphBuilder::VisitStackCheck() {
2186 439632 : PrepareEagerCheckpoint();
2187 439633 : Node* node = NewNode(javascript()->StackCheck());
2188 439633 : environment()->RecordAfterState(node, Environment::kAttachFrameState);
2189 439632 : }
2190 :
2191 162444 : void BytecodeGraphBuilder::VisitSetPendingMessage() {
2192 40611 : Node* previous_message = NewNode(javascript()->LoadMessage());
2193 81222 : NewNode(javascript()->StoreMessage(), environment()->LookupAccumulator());
2194 40611 : environment()->BindAccumulator(previous_message);
2195 40611 : }
2196 :
2197 2481324 : void BytecodeGraphBuilder::VisitReturn() {
2198 : BuildLoopExitsForFunctionExit();
2199 620331 : Node* pop_node = jsgraph()->ZeroConstant();
2200 : Node* control =
2201 1240662 : NewNode(common()->Return(), pop_node, environment()->LookupAccumulator());
2202 : MergeControlToLeaveFunction(control);
2203 620331 : }
2204 :
2205 3114 : void BytecodeGraphBuilder::VisitDebugger() {
2206 1038 : PrepareEagerCheckpoint();
2207 1038 : Node* call = NewNode(javascript()->Debugger());
2208 1038 : environment()->RecordAfterState(call, Environment::kAttachFrameState);
2209 1038 : }
2210 :
2211 : // We cannot create a graph from the debugger copy of the bytecode array.
2212 : #define DEBUG_BREAK(Name, ...) \
2213 : void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
2214 0 : DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
2215 : #undef DEBUG_BREAK
2216 :
2217 8994 : void BytecodeGraphBuilder::VisitForInPrepare() {
2218 1499 : PrepareEagerCheckpoint();
2219 : Node* receiver =
2220 2998 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2221 1499 : Node* prepare = NewNode(javascript()->ForInPrepare(), receiver);
2222 : environment()->BindRegistersToProjections(
2223 : bytecode_iterator().GetRegisterOperand(1), prepare,
2224 2998 : Environment::kAttachFrameState);
2225 1499 : }
2226 :
2227 10493 : void BytecodeGraphBuilder::VisitForInContinue() {
2228 1499 : PrepareEagerCheckpoint();
2229 : Node* index =
2230 2998 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2231 : Node* cache_length =
2232 2998 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2233 : Node* exit_cond =
2234 : NewNode(javascript()->LessThan(CompareOperationHint::kSignedSmall), index,
2235 1499 : cache_length);
2236 1499 : environment()->BindAccumulator(exit_cond, Environment::kAttachFrameState);
2237 1499 : }
2238 :
2239 14990 : void BytecodeGraphBuilder::VisitForInNext() {
2240 1499 : PrepareEagerCheckpoint();
2241 : Node* receiver =
2242 2998 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2243 : Node* index =
2244 2998 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2245 2998 : int catch_reg_pair_index = bytecode_iterator().GetRegisterOperand(2).index();
2246 : Node* cache_type = environment()->LookupRegister(
2247 1499 : interpreter::Register(catch_reg_pair_index));
2248 : Node* cache_array = environment()->LookupRegister(
2249 2998 : interpreter::Register(catch_reg_pair_index + 1));
2250 :
2251 : Node* value = NewNode(javascript()->ForInNext(), receiver, cache_array,
2252 1499 : cache_type, index);
2253 1499 : environment()->BindAccumulator(value, Environment::kAttachFrameState);
2254 1499 : }
2255 :
2256 8994 : void BytecodeGraphBuilder::VisitForInStep() {
2257 1499 : PrepareEagerCheckpoint();
2258 : Node* index =
2259 2998 : environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2260 : index = NewNode(
2261 : simplified()->SpeculativeNumberAdd(NumberOperationHint::kSignedSmall),
2262 2998 : index, jsgraph()->OneConstant());
2263 1499 : environment()->BindAccumulator(index, Environment::kAttachFrameState);
2264 1499 : }
2265 :
2266 153485 : void BytecodeGraphBuilder::VisitSuspendGenerator() {
2267 6707 : Node* state = environment()->LookupAccumulator();
2268 : Node* generator = environment()->LookupRegister(
2269 13414 : bytecode_iterator().GetRegisterOperand(0));
2270 : SuspendFlags flags = interpreter::SuspendGeneratorBytecodeFlags::Decode(
2271 6707 : bytecode_iterator().GetFlagOperand(1));
2272 : // The offsets used by the bytecode iterator are relative to a different base
2273 : // than what is used in the interpreter, hence the addition.
2274 : Node* offset =
2275 6707 : jsgraph()->Constant(bytecode_iterator().current_offset() +
2276 13414 : (BytecodeArray::kHeaderSize - kHeapObjectTag));
2277 :
2278 6707 : int register_count = environment()->register_count();
2279 6707 : int value_input_count = 3 + register_count;
2280 :
2281 6707 : Node** value_inputs = local_zone()->NewArray<Node*>(value_input_count);
2282 6707 : value_inputs[0] = generator;
2283 6707 : value_inputs[1] = state;
2284 6707 : value_inputs[2] = offset;
2285 99829 : for (int i = 0; i < register_count; ++i) {
2286 93122 : value_inputs[3 + i] =
2287 93122 : environment()->LookupRegister(interpreter::Register(i));
2288 : }
2289 :
2290 : MakeNode(javascript()->GeneratorStore(register_count, flags),
2291 6707 : value_input_count, value_inputs, false);
2292 6707 : }
2293 :
2294 111771 : void BytecodeGraphBuilder::VisitResumeGenerator() {
2295 2397 : PrepareEagerCheckpoint();
2296 :
2297 : Node* generator = environment()->LookupRegister(
2298 4794 : bytecode_iterator().GetRegisterOperand(0));
2299 :
2300 : // Bijection between registers and array indices must match that used in
2301 : // InterpreterAssembler::ExportRegisterFile.
2302 69720 : for (int i = 0; i < environment()->register_count(); ++i) {
2303 32463 : Node* value = NewNode(javascript()->GeneratorRestoreRegister(i), generator);
2304 32463 : environment()->BindRegister(interpreter::Register(i), value);
2305 : }
2306 :
2307 : Node* state =
2308 2397 : NewNode(javascript()->GeneratorRestoreContinuation(), generator);
2309 :
2310 2397 : environment()->BindAccumulator(state, Environment::kAttachFrameState);
2311 2397 : }
2312 :
2313 0 : void BytecodeGraphBuilder::VisitWide() {
2314 : // Consumed by the BytecodeArrayIterator.
2315 0 : UNREACHABLE();
2316 : }
2317 :
2318 0 : void BytecodeGraphBuilder::VisitExtraWide() {
2319 : // Consumed by the BytecodeArrayIterator.
2320 0 : UNREACHABLE();
2321 : }
2322 :
2323 0 : void BytecodeGraphBuilder::VisitIllegal() {
2324 : // Not emitted in valid bytecode.
2325 0 : UNREACHABLE();
2326 : }
2327 :
2328 0 : void BytecodeGraphBuilder::VisitNop() {}
2329 :
2330 14977886 : void BytecodeGraphBuilder::SwitchToMergeEnvironment(int current_offset) {
2331 : auto it = merge_environments_.find(current_offset);
2332 14329225 : if (it != merge_environments_.end()) {
2333 : mark_as_needing_eager_checkpoint(true);
2334 648660 : if (environment() != nullptr) {
2335 218198 : it->second->Merge(environment());
2336 : }
2337 648660 : set_environment(it->second);
2338 : }
2339 14329225 : }
2340 :
2341 27657132 : void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
2342 27519426 : if (bytecode_analysis()->IsLoopHeader(current_offset)) {
2343 : mark_as_needing_eager_checkpoint(true);
2344 : const LoopInfo& loop_info =
2345 91804 : bytecode_analysis()->GetLoopInfoFor(current_offset);
2346 :
2347 : // Add loop header.
2348 91804 : environment()->PrepareForLoop(loop_info.assignments());
2349 :
2350 45902 : BuildOSRLoopEntryPoint(current_offset);
2351 :
2352 : // Store a copy of the environment so we can connect merged back edge inputs
2353 : // to the loop header.
2354 91804 : merge_environments_[current_offset] = environment()->Copy();
2355 : }
2356 13759713 : }
2357 :
2358 2150190 : void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
2359 1075095 : BuildLoopExitsForBranch(target_offset);
2360 1075095 : Environment*& merge_environment = merge_environments_[target_offset];
2361 1075095 : if (merge_environment == nullptr) {
2362 : // Append merge nodes to the environment. We may merge here with another
2363 : // environment. So add a place holder for merge nodes. We may add redundant
2364 : // but will be eliminated in a later pass.
2365 : // TODO(mstarzinger): Be smarter about this!
2366 648660 : NewMerge();
2367 648660 : merge_environment = environment();
2368 : } else {
2369 426435 : merge_environment->Merge(environment());
2370 : }
2371 : set_environment(nullptr);
2372 1075096 : }
2373 :
2374 0 : void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
2375 676991 : exit_controls_.push_back(exit);
2376 : set_environment(nullptr);
2377 0 : }
2378 :
2379 57392 : void BytecodeGraphBuilder::BuildOSRLoopEntryPoint(int current_offset) {
2380 : DCHECK(bytecode_analysis()->IsLoopHeader(current_offset));
2381 :
2382 45902 : if (bytecode_analysis()->IsOSREntryPoint(current_offset)) {
2383 : // For OSR add a special {OsrLoopEntry} node into the current loop header.
2384 : // It will be turned into a usable entry by the OSR deconstruction.
2385 5745 : Environment* osr_env = environment()->Copy();
2386 5745 : osr_env->PrepareForOsrEntry();
2387 5745 : environment()->Merge(osr_env);
2388 : }
2389 45902 : }
2390 :
2391 436611 : void BytecodeGraphBuilder::BuildOSRNormalEntryPoint() {
2392 430866 : if (bytecode_analysis()->HasOSREntryPoint()) {
2393 : // For OSR add an {OsrNormalEntry} as the the top-level environment start.
2394 : // It will be replaced with {Dead} by the OSR deconstruction.
2395 5745 : NewNode(common()->OsrNormalEntry());
2396 : }
2397 430866 : }
2398 :
2399 2105775 : void BytecodeGraphBuilder::BuildLoopExitsForBranch(int target_offset) {
2400 1075095 : int origin_offset = bytecode_iterator().current_offset();
2401 : // Only build loop exits for forward edges.
2402 1075095 : if (target_offset > origin_offset) {
2403 : BuildLoopExitsUntilLoop(
2404 1030680 : bytecode_analysis()->GetLoopOffsetFor(target_offset));
2405 : }
2406 1075095 : }
2407 :
2408 3729438 : void BytecodeGraphBuilder::BuildLoopExitsUntilLoop(int loop_offset) {
2409 1684255 : int origin_offset = bytecode_iterator().current_offset();
2410 1684255 : int current_loop = bytecode_analysis()->GetLoopOffsetFor(origin_offset);
2411 3548976 : while (loop_offset < current_loop) {
2412 180464 : Node* loop_node = merge_environments_[current_loop]->GetControlDependency();
2413 180464 : const LoopInfo& loop_info =
2414 360928 : bytecode_analysis()->GetLoopInfoFor(current_loop);
2415 360928 : environment()->PrepareForLoopExit(loop_node, loop_info.assignments());
2416 180464 : current_loop = loop_info.parent_offset();
2417 : }
2418 1684256 : }
2419 :
2420 0 : void BytecodeGraphBuilder::BuildLoopExitsForFunctionExit() {
2421 653576 : BuildLoopExitsUntilLoop(-1);
2422 0 : }
2423 :
2424 184337 : void BytecodeGraphBuilder::BuildJump() {
2425 184337 : MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
2426 184337 : }
2427 :
2428 180747 : void BytecodeGraphBuilder::BuildJumpIf(Node* condition) {
2429 60249 : NewBranch(condition);
2430 60249 : Environment* if_false_environment = environment()->Copy();
2431 60249 : NewIfTrue();
2432 60249 : MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
2433 : set_environment(if_false_environment);
2434 60249 : NewIfFalse();
2435 60249 : }
2436 :
2437 276885 : void BytecodeGraphBuilder::BuildJumpIfNot(Node* condition) {
2438 92295 : NewBranch(condition);
2439 92295 : Environment* if_true_environment = environment()->Copy();
2440 92295 : NewIfFalse();
2441 92295 : MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
2442 : set_environment(if_true_environment);
2443 92295 : NewIfTrue();
2444 92295 : }
2445 :
2446 28044 : void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
2447 14022 : Node* accumulator = environment()->LookupAccumulator();
2448 : Node* condition =
2449 14022 : NewNode(simplified()->ReferenceEqual(), accumulator, comperand);
2450 14022 : BuildJumpIf(condition);
2451 14022 : }
2452 :
2453 16794 : void BytecodeGraphBuilder::BuildJumpIfNotEqual(Node* comperand) {
2454 8397 : Node* accumulator = environment()->LookupAccumulator();
2455 : Node* condition =
2456 8397 : NewNode(simplified()->ReferenceEqual(), accumulator, comperand);
2457 8397 : BuildJumpIfNot(condition);
2458 8397 : }
2459 :
2460 1496711 : void BytecodeGraphBuilder::BuildJumpIfFalse() {
2461 249452 : NewBranch(environment()->LookupAccumulator());
2462 249452 : Environment* if_true_environment = environment()->Copy();
2463 498904 : environment()->BindAccumulator(jsgraph()->FalseConstant());
2464 249452 : NewIfFalse();
2465 249452 : MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
2466 249451 : if_true_environment->BindAccumulator(jsgraph()->TrueConstant());
2467 : set_environment(if_true_environment);
2468 249451 : NewIfTrue();
2469 249452 : }
2470 :
2471 1202070 : void BytecodeGraphBuilder::BuildJumpIfTrue() {
2472 200345 : NewBranch(environment()->LookupAccumulator());
2473 200345 : Environment* if_false_environment = environment()->Copy();
2474 400690 : environment()->BindAccumulator(jsgraph()->TrueConstant());
2475 200345 : NewIfTrue();
2476 200345 : MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
2477 200345 : if_false_environment->BindAccumulator(jsgraph()->FalseConstant());
2478 : set_environment(if_false_environment);
2479 200345 : NewIfFalse();
2480 200345 : }
2481 :
2482 79872 : void BytecodeGraphBuilder::BuildJumpIfToBooleanTrue() {
2483 39936 : Node* accumulator = environment()->LookupAccumulator();
2484 : Node* condition =
2485 79872 : NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
2486 39936 : BuildJumpIf(condition);
2487 39936 : }
2488 :
2489 133028 : void BytecodeGraphBuilder::BuildJumpIfToBooleanFalse() {
2490 66514 : Node* accumulator = environment()->LookupAccumulator();
2491 : Node* condition =
2492 133028 : NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
2493 66514 : BuildJumpIfNot(condition);
2494 66514 : }
2495 :
2496 52152 : void BytecodeGraphBuilder::BuildJumpIfNotHole() {
2497 17384 : Node* accumulator = environment()->LookupAccumulator();
2498 : Node* condition = NewNode(simplified()->ReferenceEqual(), accumulator,
2499 34768 : jsgraph()->TheHoleConstant());
2500 17384 : BuildJumpIfNot(condition);
2501 17384 : }
2502 :
2503 12582 : void BytecodeGraphBuilder::BuildJumpIfJSReceiver() {
2504 6291 : Node* accumulator = environment()->LookupAccumulator();
2505 6291 : Node* condition = NewNode(simplified()->ObjectIsReceiver(), accumulator);
2506 6291 : BuildJumpIf(condition);
2507 6291 : }
2508 :
2509 840415 : Node* BytecodeGraphBuilder::TryBuildSimplifiedBinaryOp(const Operator* op,
2510 : Node* left, Node* right,
2511 840415 : FeedbackSlot slot) {
2512 840415 : Node* effect = environment()->GetEffectDependency();
2513 840415 : Node* control = environment()->GetControlDependency();
2514 840415 : Reduction early_reduction = type_hint_lowering().ReduceBinaryOperation(
2515 840415 : op, left, right, effect, control, slot);
2516 840415 : if (early_reduction.Changed()) {
2517 311014 : ApplyEarlyReduction(early_reduction);
2518 311014 : return early_reduction.replacement();
2519 : }
2520 : return nullptr;
2521 : }
2522 :
2523 4993 : Node* BytecodeGraphBuilder::TryBuildSimplifiedToNumber(Node* value,
2524 4993 : FeedbackSlot slot) {
2525 4993 : Node* effect = environment()->GetEffectDependency();
2526 4993 : Node* control = environment()->GetControlDependency();
2527 4993 : Reduction early_reduction = type_hint_lowering().ReduceToNumberOperation(
2528 4993 : value, effect, control, slot);
2529 4993 : if (early_reduction.Changed()) {
2530 2219 : ApplyEarlyReduction(early_reduction);
2531 2219 : return early_reduction.replacement();
2532 : }
2533 : return nullptr;
2534 : }
2535 :
2536 460689 : Node* BytecodeGraphBuilder::TryBuildSimplifiedLoadNamed(const Operator* op,
2537 : Node* receiver,
2538 916308 : FeedbackSlot slot) {
2539 : // TODO(mstarzinger,6112): This is a workaround for OSR loop entries being
2540 : // pruned from the graph by a soft-deopt. It can happen that a LoadIC that
2541 : // control-dominates the OSR entry is still in "uninitialized" state.
2542 460689 : if (bytecode_analysis()->HasOSREntryPoint()) return nullptr;
2543 455619 : Node* effect = environment()->GetEffectDependency();
2544 455619 : Node* control = environment()->GetControlDependency();
2545 455619 : Reduction early_reduction = type_hint_lowering().ReduceLoadNamedOperation(
2546 455619 : op, receiver, effect, control, slot);
2547 455619 : if (early_reduction.Changed()) {
2548 22623 : ApplyEarlyReduction(early_reduction);
2549 22623 : return early_reduction.replacement();
2550 : }
2551 : return nullptr;
2552 : }
2553 :
2554 68823 : Node* BytecodeGraphBuilder::TryBuildSimplifiedLoadKeyed(const Operator* op,
2555 : Node* receiver,
2556 : Node* key,
2557 136699 : FeedbackSlot slot) {
2558 : // TODO(mstarzinger,6112): This is a workaround for OSR loop entries being
2559 : // pruned from the graph by a soft-deopt. It can happen that a LoadIC that
2560 : // control-dominates the OSR entry is still in "uninitialized" state.
2561 68823 : if (bytecode_analysis()->HasOSREntryPoint()) return nullptr;
2562 67876 : Node* effect = environment()->GetEffectDependency();
2563 67876 : Node* control = environment()->GetControlDependency();
2564 67876 : Reduction early_reduction = type_hint_lowering().ReduceLoadKeyedOperation(
2565 67876 : op, receiver, key, effect, control, slot);
2566 67876 : if (early_reduction.Changed()) {
2567 348 : ApplyEarlyReduction(early_reduction);
2568 348 : return early_reduction.replacement();
2569 : }
2570 : return nullptr;
2571 : }
2572 :
2573 98946 : Node* BytecodeGraphBuilder::TryBuildSimplifiedStoreNamed(const Operator* op,
2574 : Node* receiver,
2575 : Node* value,
2576 197163 : FeedbackSlot slot) {
2577 : // TODO(mstarzinger,6112): This is a workaround for OSR loop entries being
2578 : // pruned from the graph by a soft-deopt. It can happen that a LoadIC that
2579 : // control-dominates the OSR entry is still in "uninitialized" state.
2580 98946 : if (bytecode_analysis()->HasOSREntryPoint()) return nullptr;
2581 98217 : Node* effect = environment()->GetEffectDependency();
2582 98217 : Node* control = environment()->GetControlDependency();
2583 98217 : Reduction early_reduction = type_hint_lowering().ReduceStoreNamedOperation(
2584 98217 : op, receiver, value, effect, control, slot);
2585 98217 : if (early_reduction.Changed()) {
2586 375 : ApplyEarlyReduction(early_reduction);
2587 375 : return early_reduction.replacement();
2588 : }
2589 : return nullptr;
2590 : }
2591 :
2592 40700 : Node* BytecodeGraphBuilder::TryBuildSimplifiedStoreKeyed(const Operator* op,
2593 : Node* receiver,
2594 : Node* key, Node* value,
2595 80060 : FeedbackSlot slot) {
2596 : // TODO(mstarzinger,6112): This is a workaround for OSR loop entries being
2597 : // pruned from the graph by a soft-deopt. It can happen that a LoadIC that
2598 : // control-dominates the OSR entry is still in "uninitialized" state.
2599 40700 : if (bytecode_analysis()->HasOSREntryPoint()) return nullptr;
2600 39360 : Node* effect = environment()->GetEffectDependency();
2601 39360 : Node* control = environment()->GetControlDependency();
2602 39360 : Reduction early_reduction = type_hint_lowering().ReduceStoreKeyedOperation(
2603 39360 : op, receiver, key, value, effect, control, slot);
2604 39360 : if (early_reduction.Changed()) {
2605 69 : ApplyEarlyReduction(early_reduction);
2606 69 : return early_reduction.replacement();
2607 : }
2608 : return nullptr;
2609 : }
2610 :
2611 649881 : void BytecodeGraphBuilder::ApplyEarlyReduction(Reduction reduction) {
2612 673296 : Node* node = reduction.replacement();
2613 : DCHECK(node->op()->HasProperty(Operator::kNoWrite));
2614 673296 : if (node->op()->EffectOutputCount() > 0) {
2615 : environment()->UpdateEffectDependency(node);
2616 : }
2617 336648 : if (IrOpcode::IsGraphTerminator(node->opcode())) {
2618 : MergeControlToLeaveFunction(node);
2619 : }
2620 336648 : }
2621 :
2622 13884469 : Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
2623 13453473 : if (size > input_buffer_size_) {
2624 430996 : size = size + kInputBufferSizeIncrement + input_buffer_size_;
2625 861993 : input_buffer_ = local_zone()->NewArray<Node*>(size);
2626 430997 : input_buffer_size_ = size;
2627 : }
2628 13453474 : return input_buffer_;
2629 : }
2630 :
2631 14329222 : void BytecodeGraphBuilder::EnterAndExitExceptionHandlers(int current_offset) {
2632 14329222 : Handle<HandlerTable> table = exception_handler_table();
2633 : int num_entries = table->NumberOfRangeEntries();
2634 :
2635 : // Potentially exit exception handlers.
2636 28697181 : while (!exception_handlers_.empty()) {
2637 1245923 : int current_end = exception_handlers_.top().end_offset_;
2638 1245923 : if (current_offset < current_end) break; // Still covered by range.
2639 : exception_handlers_.pop();
2640 : }
2641 :
2642 : // Potentially enter exception handlers.
2643 14367959 : while (current_exception_handler_ < num_entries) {
2644 : int next_start = table->GetRangeStart(current_exception_handler_);
2645 1522708 : if (current_offset < next_start) break; // Not yet covered by range.
2646 77474 : int next_end = table->GetRangeEnd(current_exception_handler_);
2647 77474 : int next_handler = table->GetRangeHandler(current_exception_handler_);
2648 77474 : int context_register = table->GetRangeData(current_exception_handler_);
2649 : exception_handlers_.push(
2650 77474 : {next_start, next_end, next_handler, context_register});
2651 38737 : current_exception_handler_++;
2652 : }
2653 14329222 : }
2654 :
2655 37058386 : Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
2656 : Node* const* value_inputs,
2657 59303723 : bool incomplete) {
2658 : DCHECK_EQ(op->ValueInputCount(), value_input_count);
2659 :
2660 12352792 : bool has_context = OperatorProperties::HasContextInput(op);
2661 12352798 : bool has_frame_state = OperatorProperties::HasFrameStateInput(op);
2662 12352797 : bool has_control = op->ControlInputCount() == 1;
2663 12352797 : bool has_effect = op->EffectInputCount() == 1;
2664 :
2665 : DCHECK_LT(op->ControlInputCount(), 2);
2666 : DCHECK_LT(op->EffectInputCount(), 2);
2667 :
2668 53124949 : Node* result = nullptr;
2669 12352797 : if (!has_context && !has_frame_state && !has_control && !has_effect) {
2670 2161262 : result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
2671 : } else {
2672 11272166 : bool inside_handler = !exception_handlers_.empty();
2673 : int input_count_with_deps = value_input_count;
2674 11272166 : if (has_context) ++input_count_with_deps;
2675 11272166 : if (has_frame_state) ++input_count_with_deps;
2676 11272166 : if (has_control) ++input_count_with_deps;
2677 11272166 : if (has_effect) ++input_count_with_deps;
2678 11272166 : Node** buffer = EnsureInputBufferSize(input_count_with_deps);
2679 11272172 : memcpy(buffer, value_inputs, kPointerSize * value_input_count);
2680 11272172 : Node** current_input = buffer + value_input_count;
2681 11272172 : if (has_context) {
2682 9312818 : *current_input++ = environment()->Context();
2683 : }
2684 11272172 : if (has_frame_state) {
2685 : // The frame state will be inserted later. Here we misuse the {Dead} node
2686 : // as a sentinel to be later overwritten with the real frame state by the
2687 : // calls to {PrepareFrameState} within individual visitor methods.
2688 11872048 : *current_input++ = jsgraph()->Dead();
2689 : }
2690 11272170 : if (has_effect) {
2691 16072322 : *current_input++ = environment()->GetEffectDependency();
2692 : }
2693 11272170 : if (has_control) {
2694 10579106 : *current_input++ = environment()->GetControlDependency();
2695 : }
2696 22544340 : result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
2697 : // Update the current control dependency for control-producing nodes.
2698 22544388 : if (result->op()->ControlOutputCount() > 0) {
2699 : environment()->UpdateControlDependency(result);
2700 : }
2701 : // Update the current effect dependency for effect-producing nodes.
2702 22544388 : if (result->op()->EffectOutputCount() > 0) {
2703 : environment()->UpdateEffectDependency(result);
2704 : }
2705 : // Add implicit exception continuation for throwing nodes.
2706 11272194 : if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
2707 288418 : int handler_offset = exception_handlers_.top().handler_offset_;
2708 288418 : int context_index = exception_handlers_.top().context_register_;
2709 : interpreter::Register context_register(context_index);
2710 288418 : Environment* success_env = environment()->Copy();
2711 288418 : const Operator* op = common()->IfException();
2712 288418 : Node* effect = environment()->GetEffectDependency();
2713 : Node* on_exception = graph()->NewNode(op, effect, result);
2714 288418 : Node* context = environment()->LookupRegister(context_register);
2715 : environment()->UpdateControlDependency(on_exception);
2716 : environment()->UpdateEffectDependency(on_exception);
2717 288418 : environment()->BindAccumulator(on_exception);
2718 : environment()->SetContext(context);
2719 288418 : MergeIntoSuccessorEnvironment(handler_offset);
2720 : set_environment(success_env);
2721 : }
2722 : // Add implicit success continuation for throwing nodes.
2723 11272194 : if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
2724 288418 : const Operator* if_success = common()->IfSuccess();
2725 : Node* on_success = graph()->NewNode(if_success, result);
2726 : environment()->UpdateControlDependency(on_success);
2727 : }
2728 : // Ensure checkpoints are created after operations with side-effects.
2729 19308367 : if (has_effect && !result->op()->HasProperty(Operator::kNoWrite)) {
2730 : mark_as_needing_eager_checkpoint(true);
2731 : }
2732 : }
2733 :
2734 12352825 : return result;
2735 : }
2736 :
2737 :
2738 3515181 : Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
2739 1757591 : const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
2740 1757591 : Node** buffer = EnsureInputBufferSize(count + 1);
2741 : MemsetPointer(buffer, input, count);
2742 1757590 : buffer[count] = control;
2743 1757590 : return graph()->NewNode(phi_op, count + 1, buffer, true);
2744 : }
2745 :
2746 :
2747 423734 : Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
2748 847468 : Node* control) {
2749 423734 : const Operator* phi_op = common()->EffectPhi(count);
2750 423734 : Node** buffer = EnsureInputBufferSize(count + 1);
2751 : MemsetPointer(buffer, input, count);
2752 423734 : buffer[count] = control;
2753 423734 : return graph()->NewNode(phi_op, count + 1, buffer, true);
2754 : }
2755 :
2756 :
2757 1536648 : Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
2758 1536648 : int inputs = control->op()->ControlInputCount() + 1;
2759 768324 : if (control->opcode() == IrOpcode::kLoop) {
2760 : // Control node for loop exists, add input.
2761 50160 : const Operator* op = common()->Loop(inputs);
2762 50160 : control->AppendInput(graph_zone(), other);
2763 50160 : NodeProperties::ChangeOp(control, op);
2764 718164 : } else if (control->opcode() == IrOpcode::kMerge) {
2765 : // Control node for merge exists, add input.
2766 718164 : const Operator* op = common()->Merge(inputs);
2767 718164 : control->AppendInput(graph_zone(), other);
2768 718164 : NodeProperties::ChangeOp(control, op);
2769 : } else {
2770 : // Control node is a singleton, introduce a merge.
2771 0 : const Operator* op = common()->Merge(inputs);
2772 0 : Node* merge_inputs[] = {control, other};
2773 0 : control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
2774 : }
2775 768324 : return control;
2776 : }
2777 :
2778 :
2779 1536650 : Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
2780 1126998 : Node* control) {
2781 768325 : int inputs = control->op()->ControlInputCount();
2782 1139719 : if (value->opcode() == IrOpcode::kEffectPhi &&
2783 371394 : NodeProperties::GetControlInput(value) == control) {
2784 : // Phi already exists, add input.
2785 717346 : value->InsertInput(graph_zone(), inputs - 1, other);
2786 358673 : NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
2787 409652 : } else if (value != other) {
2788 : // Phi does not exist yet, introduce one.
2789 377832 : value = NewEffectPhi(inputs, value, control);
2790 377832 : value->ReplaceInput(inputs - 1, other);
2791 : }
2792 768325 : return value;
2793 : }
2794 :
2795 :
2796 31232854 : Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
2797 19037581 : Node* control) {
2798 15616427 : int inputs = control->op()->ControlInputCount();
2799 21676970 : if (value->opcode() == IrOpcode::kPhi &&
2800 6060546 : NodeProperties::GetControlInput(value) == control) {
2801 : // Phi already exists, add input.
2802 6842310 : value->InsertInput(graph_zone(), inputs - 1, other);
2803 : NodeProperties::ChangeOp(
2804 3421154 : value, common()->Phi(MachineRepresentation::kTagged, inputs));
2805 12195269 : } else if (value != other) {
2806 : // Phi does not exist yet, introduce one.
2807 1377594 : value = NewPhi(inputs, value, control);
2808 1377593 : value->ReplaceInput(inputs - 1, other);
2809 : }
2810 15616423 : return value;
2811 : }
2812 :
2813 14329212 : void BytecodeGraphBuilder::UpdateCurrentSourcePosition(
2814 32360506 : SourcePositionTableIterator* it, int offset) {
2815 28658424 : if (it->done()) return;
2816 :
2817 13126289 : if (it->code_offset() == offset) {
2818 : source_positions_->SetCurrentPosition(SourcePosition(
2819 4905005 : it->source_position().ScriptOffset(), start_position_.InliningId()));
2820 4905005 : it->Advance();
2821 : } else {
2822 : DCHECK_GT(it->code_offset(), offset);
2823 : }
2824 : }
2825 :
2826 : } // namespace compiler
2827 : } // namespace internal
2828 : } // namespace v8
|