| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/bytecode-graph-builder.h" | 5 #include "src/compiler/bytecode-graph-builder.h" |
| 6 | 6 |
| 7 #include "src/ast/ast.h" | 7 #include "src/ast/ast.h" |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
| 10 #include "src/compiler/compiler-source-position-table.h" | 10 #include "src/compiler/compiler-source-position-table.h" |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 | 61 |
| 62 // Control dependency tracked by this environment. | 62 // Control dependency tracked by this environment. |
| 63 Node* GetControlDependency() const { return control_dependency_; } | 63 Node* GetControlDependency() const { return control_dependency_; } |
| 64 void UpdateControlDependency(Node* dependency) { | 64 void UpdateControlDependency(Node* dependency) { |
| 65 control_dependency_ = dependency; | 65 control_dependency_ = dependency; |
| 66 } | 66 } |
| 67 | 67 |
| 68 Node* Context() const { return context_; } | 68 Node* Context() const { return context_; } |
| 69 void SetContext(Node* new_context) { context_ = new_context; } | 69 void SetContext(Node* new_context) { context_ = new_context; } |
| 70 | 70 |
| 71 Environment* CopyForConditional(); | 71 Environment* Copy(); |
| 72 Environment* CopyForLoop(); | |
| 73 Environment* CopyForOsrEntry(); | |
| 74 void Merge(Environment* other); | 72 void Merge(Environment* other); |
| 73 |
| 75 void PrepareForOsrEntry(); | 74 void PrepareForOsrEntry(); |
| 76 | 75 void PrepareForLoop(const BytecodeLoopAssignments& assignments); |
| 77 void PrepareForLoopExit(Node* loop); | 76 void PrepareForLoopExit(Node* loop, |
| 77 const BytecodeLoopAssignments& assignments); |
| 78 | 78 |
| 79 private: | 79 private: |
| 80 explicit Environment(const Environment* copy); | 80 explicit Environment(const Environment* copy); |
| 81 void PrepareForLoop(); | |
| 82 | 81 |
| 83 bool StateValuesRequireUpdate(Node** state_values, Node** values, int count); | 82 bool StateValuesRequireUpdate(Node** state_values, Node** values, int count); |
| 84 void UpdateStateValues(Node** state_values, Node** values, int count); | 83 void UpdateStateValues(Node** state_values, Node** values, int count); |
| 85 void UpdateStateValuesWithCache(Node** state_values, Node** values, | 84 void UpdateStateValuesWithCache(Node** state_values, Node** values, |
| 86 int count); | 85 int count); |
| 87 | 86 |
| 88 int RegisterToValuesIndex(interpreter::Register the_register) const; | 87 int RegisterToValuesIndex(interpreter::Register the_register) const; |
| 89 | 88 |
| 90 Zone* zone() const { return builder_->local_zone(); } | 89 Zone* zone() const { return builder_->local_zone(); } |
| 91 Graph* graph() const { return builder_->graph(); } | 90 Graph* graph() const { return builder_->graph(); } |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 } | 242 } |
| 244 } | 243 } |
| 245 | 244 |
| 246 void BytecodeGraphBuilder::Environment::RecordAfterState( | 245 void BytecodeGraphBuilder::Environment::RecordAfterState( |
| 247 Node* node, FrameStateAttachmentMode mode) { | 246 Node* node, FrameStateAttachmentMode mode) { |
| 248 if (mode == FrameStateAttachmentMode::kAttachFrameState) { | 247 if (mode == FrameStateAttachmentMode::kAttachFrameState) { |
| 249 builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore()); | 248 builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore()); |
| 250 } | 249 } |
| 251 } | 250 } |
| 252 | 251 |
| 253 | 252 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::Environment::Copy() { |
| 254 BytecodeGraphBuilder::Environment* | |
| 255 BytecodeGraphBuilder::Environment::CopyForLoop() { | |
| 256 PrepareForLoop(); | |
| 257 return new (zone()) Environment(this); | 253 return new (zone()) Environment(this); |
| 258 } | 254 } |
| 259 | 255 |
| 260 BytecodeGraphBuilder::Environment* | |
| 261 BytecodeGraphBuilder::Environment::CopyForOsrEntry() { | |
| 262 return new (zone()) Environment(this); | |
| 263 } | |
| 264 | |
| 265 BytecodeGraphBuilder::Environment* | |
| 266 BytecodeGraphBuilder::Environment::CopyForConditional() { | |
| 267 return new (zone()) Environment(this); | |
| 268 } | |
| 269 | |
| 270 | 256 |
| 271 void BytecodeGraphBuilder::Environment::Merge( | 257 void BytecodeGraphBuilder::Environment::Merge( |
| 272 BytecodeGraphBuilder::Environment* other) { | 258 BytecodeGraphBuilder::Environment* other) { |
| 273 // Create a merge of the control dependencies of both environments and update | 259 // Create a merge of the control dependencies of both environments and update |
| 274 // the current environment's control dependency accordingly. | 260 // the current environment's control dependency accordingly. |
| 275 Node* control = builder()->MergeControl(GetControlDependency(), | 261 Node* control = builder()->MergeControl(GetControlDependency(), |
| 276 other->GetControlDependency()); | 262 other->GetControlDependency()); |
| 277 UpdateControlDependency(control); | 263 UpdateControlDependency(control); |
| 278 | 264 |
| 279 // Create a merge of the effect dependencies of both environments and update | 265 // Create a merge of the effect dependencies of both environments and update |
| 280 // the current environment's effect dependency accordingly. | 266 // the current environment's effect dependency accordingly. |
| 281 Node* effect = builder()->MergeEffect(GetEffectDependency(), | 267 Node* effect = builder()->MergeEffect(GetEffectDependency(), |
| 282 other->GetEffectDependency(), control); | 268 other->GetEffectDependency(), control); |
| 283 UpdateEffectDependency(effect); | 269 UpdateEffectDependency(effect); |
| 284 | 270 |
| 285 // Introduce Phi nodes for values that have differing input at merge points, | 271 // Introduce Phi nodes for values that have differing input at merge points, |
| 286 // potentially extending an existing Phi node if possible. | 272 // potentially extending an existing Phi node if possible. |
| 287 context_ = builder()->MergeValue(context_, other->context_, control); | 273 context_ = builder()->MergeValue(context_, other->context_, control); |
| 288 for (size_t i = 0; i < values_.size(); i++) { | 274 for (size_t i = 0; i < values_.size(); i++) { |
| 289 values_[i] = builder()->MergeValue(values_[i], other->values_[i], control); | 275 values_[i] = builder()->MergeValue(values_[i], other->values_[i], control); |
| 290 } | 276 } |
| 291 } | 277 } |
| 292 | 278 |
| 293 | 279 void BytecodeGraphBuilder::Environment::PrepareForLoop( |
| 294 void BytecodeGraphBuilder::Environment::PrepareForLoop() { | 280 const BytecodeLoopAssignments& assignments) { |
| 295 // Create a control node for the loop header. | 281 // Create a control node for the loop header. |
| 296 Node* control = builder()->NewLoop(); | 282 Node* control = builder()->NewLoop(); |
| 297 | 283 |
| 298 // Create a Phi for external effects. | 284 // Create a Phi for external effects. |
| 299 Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control); | 285 Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control); |
| 300 UpdateEffectDependency(effect); | 286 UpdateEffectDependency(effect); |
| 301 | 287 |
| 302 // Assume everything in the loop is updated. | 288 // Create Phis for any values that may be updated by the end of the loop. |
| 303 context_ = builder()->NewPhi(1, context_, control); | 289 context_ = builder()->NewPhi(1, context_, control); |
| 304 int size = static_cast<int>(values()->size()); | 290 for (int i = 0; i < parameter_count(); i++) { |
| 305 for (int i = 0; i < size; i++) { | 291 if (assignments.ContainsParameter(i)) { |
| 306 values()->at(i) = builder()->NewPhi(1, values()->at(i), control); | 292 values_[i] = builder()->NewPhi(1, values_[i], control); |
| 293 } |
| 294 } |
| 295 for (int i = 0; i < register_count(); i++) { |
| 296 if (assignments.ContainsLocal(i)) { |
| 297 int index = register_base() + i; |
| 298 values_[index] = builder()->NewPhi(1, values_[index], control); |
| 299 } |
| 300 } |
| 301 |
| 302 if (assignments.ContainsAccumulator()) { |
| 303 values_[accumulator_base()] = |
| 304 builder()->NewPhi(1, values_[accumulator_base()], control); |
| 307 } | 305 } |
| 308 | 306 |
| 309 // Connect to the loop end. | 307 // Connect to the loop end. |
| 310 Node* terminate = builder()->graph()->NewNode( | 308 Node* terminate = builder()->graph()->NewNode( |
| 311 builder()->common()->Terminate(), effect, control); | 309 builder()->common()->Terminate(), effect, control); |
| 312 builder()->exit_controls_.push_back(terminate); | 310 builder()->exit_controls_.push_back(terminate); |
| 313 } | 311 } |
| 314 | 312 |
| 315 void BytecodeGraphBuilder::Environment::PrepareForOsrEntry() { | 313 void BytecodeGraphBuilder::Environment::PrepareForOsrEntry() { |
| 316 DCHECK_EQ(IrOpcode::kLoop, GetControlDependency()->opcode()); | 314 DCHECK_EQ(IrOpcode::kLoop, GetControlDependency()->opcode()); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 } | 359 } |
| 362 DCHECK_EQ((*state_values)->InputCount(), count); | 360 DCHECK_EQ((*state_values)->InputCount(), count); |
| 363 for (int i = 0; i < count; i++) { | 361 for (int i = 0; i < count; i++) { |
| 364 if ((*state_values)->InputAt(i) != values[i]) { | 362 if ((*state_values)->InputAt(i) != values[i]) { |
| 365 return true; | 363 return true; |
| 366 } | 364 } |
| 367 } | 365 } |
| 368 return false; | 366 return false; |
| 369 } | 367 } |
| 370 | 368 |
| 371 void BytecodeGraphBuilder::Environment::PrepareForLoopExit(Node* loop) { | 369 void BytecodeGraphBuilder::Environment::PrepareForLoopExit( |
| 370 Node* loop, const BytecodeLoopAssignments& assignments) { |
| 372 DCHECK_EQ(loop->opcode(), IrOpcode::kLoop); | 371 DCHECK_EQ(loop->opcode(), IrOpcode::kLoop); |
| 373 | 372 |
| 374 Node* control = GetControlDependency(); | 373 Node* control = GetControlDependency(); |
| 375 | 374 |
| 376 // Create the loop exit node. | 375 // Create the loop exit node. |
| 377 Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop); | 376 Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop); |
| 378 UpdateControlDependency(loop_exit); | 377 UpdateControlDependency(loop_exit); |
| 379 | 378 |
| 380 // Rename the effect. | 379 // Rename the effect. |
| 381 Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(), | 380 Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(), |
| 382 GetEffectDependency(), loop_exit); | 381 GetEffectDependency(), loop_exit); |
| 383 UpdateEffectDependency(effect_rename); | 382 UpdateEffectDependency(effect_rename); |
| 384 | 383 |
| 385 // TODO(jarin) We should also rename context here. However, uncoditional | 384 // TODO(jarin) We should also rename context here. However, unconditional |
| 386 // renaming confuses global object and native context specialization. | 385 // renaming confuses global object and native context specialization. |
| 387 // We should only rename if the context is assigned in the loop. | 386 // We should only rename if the context is assigned in the loop. |
| 388 | 387 |
| 389 // Rename the environmnent values. | 388 // Rename the environment values if they were assigned in the loop. |
| 390 for (size_t i = 0; i < values_.size(); i++) { | 389 for (int i = 0; i < parameter_count(); i++) { |
| 391 Node* rename = | 390 if (assignments.ContainsParameter(i)) { |
| 392 graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit); | 391 Node* rename = |
| 393 values_[i] = rename; | 392 graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit); |
| 393 values_[i] = rename; |
| 394 } |
| 395 } |
| 396 for (int i = 0; i < register_count(); i++) { |
| 397 if (assignments.ContainsLocal(i)) { |
| 398 Node* rename = graph()->NewNode(common()->LoopExitValue(), |
| 399 values_[register_base() + i], loop_exit); |
| 400 values_[register_base() + i] = rename; |
| 401 } |
| 402 } |
| 403 |
| 404 if (assignments.ContainsAccumulator()) { |
| 405 Node* rename = graph()->NewNode(common()->LoopExitValue(), |
| 406 values_[accumulator_base()], loop_exit); |
| 407 values_[accumulator_base()] = rename; |
| 394 } | 408 } |
| 395 } | 409 } |
| 396 | 410 |
| 397 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, | 411 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, |
| 398 Node** values, | 412 Node** values, |
| 399 int count) { | 413 int count) { |
| 400 if (StateValuesRequireUpdate(state_values, values, count)) { | 414 if (StateValuesRequireUpdate(state_values, values, count)) { |
| 401 const Operator* op = common()->StateValues(count); | 415 const Operator* op = common()->StateValues(count); |
| 402 (*state_values) = graph()->NewNode(op, count, values); | 416 (*state_values) = graph()->NewNode(op, count, values); |
| 403 } | 417 } |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 | 612 |
| 599 Node* frame_state_after = environment()->Checkpoint( | 613 Node* frame_state_after = environment()->Checkpoint( |
| 600 bailout_id, combine, has_exception, liveness_after); | 614 bailout_id, combine, has_exception, liveness_after); |
| 601 NodeProperties::ReplaceFrameStateInput(node, frame_state_after); | 615 NodeProperties::ReplaceFrameStateInput(node, frame_state_after); |
| 602 } | 616 } |
| 603 } | 617 } |
| 604 | 618 |
| 605 void BytecodeGraphBuilder::VisitBytecodes(bool stack_check) { | 619 void BytecodeGraphBuilder::VisitBytecodes(bool stack_check) { |
| 606 BytecodeAnalysis bytecode_analysis(bytecode_array(), local_zone(), | 620 BytecodeAnalysis bytecode_analysis(bytecode_array(), local_zone(), |
| 607 FLAG_analyze_environment_liveness); | 621 FLAG_analyze_environment_liveness); |
| 608 bytecode_analysis.Analyze(); | 622 bytecode_analysis.Analyze(osr_ast_id_); |
| 609 set_bytecode_analysis(&bytecode_analysis); | 623 set_bytecode_analysis(&bytecode_analysis); |
| 610 | 624 |
| 611 interpreter::BytecodeArrayIterator iterator(bytecode_array()); | 625 interpreter::BytecodeArrayIterator iterator(bytecode_array()); |
| 612 set_bytecode_iterator(&iterator); | 626 set_bytecode_iterator(&iterator); |
| 613 SourcePositionTableIterator source_position_iterator( | 627 SourcePositionTableIterator source_position_iterator( |
| 614 bytecode_array()->source_position_table()); | 628 bytecode_array()->source_position_table()); |
| 615 | 629 |
| 616 if (FLAG_trace_environment_liveness) { | 630 if (FLAG_trace_environment_liveness) { |
| 617 OFStream of(stdout); | 631 OFStream of(stdout); |
| 618 | 632 |
| 619 bytecode_analysis.PrintLivenessTo(of); | 633 bytecode_analysis.PrintLivenessTo(of); |
| 620 } | 634 } |
| 621 | 635 |
| 622 BuildOSRNormalEntryPoint(); | 636 BuildOSRNormalEntryPoint(); |
| 623 | 637 |
| 624 for (; !iterator.done(); iterator.Advance()) { | 638 for (; !iterator.done(); iterator.Advance()) { |
| 625 int current_offset = iterator.current_offset(); | 639 int current_offset = iterator.current_offset(); |
| 626 UpdateCurrentSourcePosition(&source_position_iterator, current_offset); | 640 UpdateCurrentSourcePosition(&source_position_iterator, current_offset); |
| 627 EnterAndExitExceptionHandlers(current_offset); | 641 EnterAndExitExceptionHandlers(current_offset); |
| 628 SwitchToMergeEnvironment(current_offset); | 642 SwitchToMergeEnvironment(current_offset); |
| 629 if (environment() != nullptr) { | 643 if (environment() != nullptr) { |
| 630 BuildLoopHeaderEnvironment(current_offset); | 644 BuildLoopHeaderEnvironment(current_offset); |
| 631 BuildOSRLoopEntryPoint(current_offset); | |
| 632 | 645 |
| 633 // Skip the first stack check if stack_check is false | 646 // Skip the first stack check if stack_check is false |
| 634 if (!stack_check && | 647 if (!stack_check && |
| 635 iterator.current_bytecode() == interpreter::Bytecode::kStackCheck) { | 648 iterator.current_bytecode() == interpreter::Bytecode::kStackCheck) { |
| 636 stack_check = true; | 649 stack_check = true; |
| 637 continue; | 650 continue; |
| 638 } | 651 } |
| 639 | 652 |
| 640 switch (iterator.current_bytecode()) { | 653 switch (iterator.current_bytecode()) { |
| 641 #define BYTECODE_CASE(name, ...) \ | 654 #define BYTECODE_CASE(name, ...) \ |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 // the same scope as the variable itself has no way of shadowing it. | 861 // the same scope as the variable itself has no way of shadowing it. |
| 849 for (uint32_t d = 0; d < depth; d++) { | 862 for (uint32_t d = 0; d < depth; d++) { |
| 850 Node* extension_slot = | 863 Node* extension_slot = |
| 851 NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false)); | 864 NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX, false)); |
| 852 | 865 |
| 853 Node* check_no_extension = | 866 Node* check_no_extension = |
| 854 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), | 867 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
| 855 extension_slot, jsgraph()->TheHoleConstant()); | 868 extension_slot, jsgraph()->TheHoleConstant()); |
| 856 | 869 |
| 857 NewBranch(check_no_extension); | 870 NewBranch(check_no_extension); |
| 858 Environment* true_environment = environment()->CopyForConditional(); | 871 Environment* true_environment = environment()->Copy(); |
| 859 | 872 |
| 860 { | 873 { |
| 861 NewIfFalse(); | 874 NewIfFalse(); |
| 862 // If there is an extension, merge into the slow path. | 875 // If there is an extension, merge into the slow path. |
| 863 if (slow_environment == nullptr) { | 876 if (slow_environment == nullptr) { |
| 864 slow_environment = environment(); | 877 slow_environment = environment(); |
| 865 NewMerge(); | 878 NewMerge(); |
| 866 } else { | 879 } else { |
| 867 slow_environment->Merge(environment()); | 880 slow_environment->Merge(environment()); |
| 868 } | 881 } |
| (...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1894 if (it != merge_environments_.end()) { | 1907 if (it != merge_environments_.end()) { |
| 1895 if (environment() != nullptr) { | 1908 if (environment() != nullptr) { |
| 1896 it->second->Merge(environment()); | 1909 it->second->Merge(environment()); |
| 1897 } | 1910 } |
| 1898 set_environment(it->second); | 1911 set_environment(it->second); |
| 1899 } | 1912 } |
| 1900 } | 1913 } |
| 1901 | 1914 |
| 1902 void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) { | 1915 void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) { |
| 1903 if (bytecode_analysis()->IsLoopHeader(current_offset)) { | 1916 if (bytecode_analysis()->IsLoopHeader(current_offset)) { |
| 1904 // Add loop header and store a copy so we can connect merged back | 1917 const LoopInfo& loop_info = |
| 1905 // edge inputs to the loop header. | 1918 bytecode_analysis()->GetLoopInfoFor(current_offset); |
| 1906 merge_environments_[current_offset] = environment()->CopyForLoop(); | 1919 |
| 1920 // Add loop header. |
| 1921 environment()->PrepareForLoop(loop_info.assignments()); |
| 1922 |
| 1923 BuildOSRLoopEntryPoint(current_offset); |
| 1924 |
| 1925 // Store a copy of the environment so we can connect merged back edge inputs |
| 1926 // to the loop header. |
| 1927 merge_environments_[current_offset] = environment()->Copy(); |
| 1907 } | 1928 } |
| 1908 } | 1929 } |
| 1909 | 1930 |
| 1910 void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) { | 1931 void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) { |
| 1911 BuildLoopExitsForBranch(target_offset); | 1932 BuildLoopExitsForBranch(target_offset); |
| 1912 Environment*& merge_environment = merge_environments_[target_offset]; | 1933 Environment*& merge_environment = merge_environments_[target_offset]; |
| 1913 if (merge_environment == nullptr) { | 1934 if (merge_environment == nullptr) { |
| 1914 // Append merge nodes to the environment. We may merge here with another | 1935 // Append merge nodes to the environment. We may merge here with another |
| 1915 // environment. So add a place holder for merge nodes. We may add redundant | 1936 // environment. So add a place holder for merge nodes. We may add redundant |
| 1916 // but will be eliminated in a later pass. | 1937 // but will be eliminated in a later pass. |
| 1917 // TODO(mstarzinger): Be smarter about this! | 1938 // TODO(mstarzinger): Be smarter about this! |
| 1918 NewMerge(); | 1939 NewMerge(); |
| 1919 merge_environment = environment(); | 1940 merge_environment = environment(); |
| 1920 } else { | 1941 } else { |
| 1921 merge_environment->Merge(environment()); | 1942 merge_environment->Merge(environment()); |
| 1922 } | 1943 } |
| 1923 set_environment(nullptr); | 1944 set_environment(nullptr); |
| 1924 } | 1945 } |
| 1925 | 1946 |
| 1926 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) { | 1947 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) { |
| 1927 exit_controls_.push_back(exit); | 1948 exit_controls_.push_back(exit); |
| 1928 set_environment(nullptr); | 1949 set_environment(nullptr); |
| 1929 } | 1950 } |
| 1930 | 1951 |
| 1931 void BytecodeGraphBuilder::BuildOSRLoopEntryPoint(int current_offset) { | 1952 void BytecodeGraphBuilder::BuildOSRLoopEntryPoint(int current_offset) { |
| 1953 DCHECK(bytecode_analysis()->IsLoopHeader(current_offset)); |
| 1954 |
| 1932 if (!osr_ast_id_.IsNone() && osr_loop_offset_ == current_offset) { | 1955 if (!osr_ast_id_.IsNone() && osr_loop_offset_ == current_offset) { |
| 1933 // For OSR add a special {OsrLoopEntry} node into the current loop header. | 1956 // For OSR add a special {OsrLoopEntry} node into the current loop header. |
| 1934 // It will be turned into a usable entry by the OSR deconstruction. | 1957 // It will be turned into a usable entry by the OSR deconstruction. |
| 1935 Environment* loop_env = merge_environments_[current_offset]; | 1958 Environment* osr_env = environment()->Copy(); |
| 1936 Environment* osr_env = loop_env->CopyForOsrEntry(); | |
| 1937 osr_env->PrepareForOsrEntry(); | 1959 osr_env->PrepareForOsrEntry(); |
| 1938 loop_env->Merge(osr_env); | 1960 environment()->Merge(osr_env); |
| 1939 } | 1961 } |
| 1940 } | 1962 } |
| 1941 | 1963 |
| 1942 void BytecodeGraphBuilder::BuildOSRNormalEntryPoint() { | 1964 void BytecodeGraphBuilder::BuildOSRNormalEntryPoint() { |
| 1943 if (!osr_ast_id_.IsNone()) { | 1965 if (!osr_ast_id_.IsNone()) { |
| 1944 // For OSR add an {OsrNormalEntry} as the the top-level environment start. | 1966 // For OSR add an {OsrNormalEntry} as the the top-level environment start. |
| 1945 // It will be replaced with {Dead} by the OSR deconstruction. | 1967 // It will be replaced with {Dead} by the OSR deconstruction. |
| 1946 NewNode(common()->OsrNormalEntry()); | 1968 NewNode(common()->OsrNormalEntry()); |
| 1947 // Translate the offset of the jump instruction to the jump target offset of | 1969 // Translate the offset of the jump instruction to the jump target offset of |
| 1948 // that instruction so that the derived BailoutId points to the loop header. | 1970 // that instruction so that the derived BailoutId points to the loop header. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1959 BuildLoopExitsUntilLoop( | 1981 BuildLoopExitsUntilLoop( |
| 1960 bytecode_analysis()->GetLoopOffsetFor(target_offset)); | 1982 bytecode_analysis()->GetLoopOffsetFor(target_offset)); |
| 1961 } | 1983 } |
| 1962 } | 1984 } |
| 1963 | 1985 |
| 1964 void BytecodeGraphBuilder::BuildLoopExitsUntilLoop(int loop_offset) { | 1986 void BytecodeGraphBuilder::BuildLoopExitsUntilLoop(int loop_offset) { |
| 1965 int origin_offset = bytecode_iterator().current_offset(); | 1987 int origin_offset = bytecode_iterator().current_offset(); |
| 1966 int current_loop = bytecode_analysis()->GetLoopOffsetFor(origin_offset); | 1988 int current_loop = bytecode_analysis()->GetLoopOffsetFor(origin_offset); |
| 1967 while (loop_offset < current_loop) { | 1989 while (loop_offset < current_loop) { |
| 1968 Node* loop_node = merge_environments_[current_loop]->GetControlDependency(); | 1990 Node* loop_node = merge_environments_[current_loop]->GetControlDependency(); |
| 1969 environment()->PrepareForLoopExit(loop_node); | 1991 const LoopInfo& loop_info = |
| 1970 current_loop = bytecode_analysis()->GetParentLoopFor(current_loop); | 1992 bytecode_analysis()->GetLoopInfoFor(current_loop); |
| 1993 environment()->PrepareForLoopExit(loop_node, loop_info.assignments()); |
| 1994 current_loop = loop_info.parent_offset(); |
| 1971 } | 1995 } |
| 1972 } | 1996 } |
| 1973 | 1997 |
| 1974 void BytecodeGraphBuilder::BuildLoopExitsForFunctionExit() { | 1998 void BytecodeGraphBuilder::BuildLoopExitsForFunctionExit() { |
| 1975 BuildLoopExitsUntilLoop(-1); | 1999 BuildLoopExitsUntilLoop(-1); |
| 1976 } | 2000 } |
| 1977 | 2001 |
| 1978 void BytecodeGraphBuilder::BuildJump() { | 2002 void BytecodeGraphBuilder::BuildJump() { |
| 1979 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset()); | 2003 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset()); |
| 1980 } | 2004 } |
| 1981 | 2005 |
| 1982 void BytecodeGraphBuilder::BuildJumpIf(Node* condition) { | 2006 void BytecodeGraphBuilder::BuildJumpIf(Node* condition) { |
| 1983 NewBranch(condition); | 2007 NewBranch(condition); |
| 1984 Environment* if_false_environment = environment()->CopyForConditional(); | 2008 Environment* if_false_environment = environment()->Copy(); |
| 1985 NewIfTrue(); | 2009 NewIfTrue(); |
| 1986 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset()); | 2010 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset()); |
| 1987 set_environment(if_false_environment); | 2011 set_environment(if_false_environment); |
| 1988 NewIfFalse(); | 2012 NewIfFalse(); |
| 1989 } | 2013 } |
| 1990 | 2014 |
| 1991 void BytecodeGraphBuilder::BuildJumpIfNot(Node* condition) { | 2015 void BytecodeGraphBuilder::BuildJumpIfNot(Node* condition) { |
| 1992 NewBranch(condition); | 2016 NewBranch(condition); |
| 1993 Environment* if_true_environment = environment()->CopyForConditional(); | 2017 Environment* if_true_environment = environment()->Copy(); |
| 1994 NewIfFalse(); | 2018 NewIfFalse(); |
| 1995 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset()); | 2019 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset()); |
| 1996 set_environment(if_true_environment); | 2020 set_environment(if_true_environment); |
| 1997 NewIfTrue(); | 2021 NewIfTrue(); |
| 1998 } | 2022 } |
| 1999 | 2023 |
| 2000 void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) { | 2024 void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) { |
| 2001 Node* accumulator = environment()->LookupAccumulator(); | 2025 Node* accumulator = environment()->LookupAccumulator(); |
| 2002 Node* condition = | 2026 Node* condition = |
| 2003 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), | 2027 NewNode(javascript()->StrictEqual(CompareOperationHint::kAny), |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2121 } | 2145 } |
| 2122 // Update the current effect dependency for effect-producing nodes. | 2146 // Update the current effect dependency for effect-producing nodes. |
| 2123 if (result->op()->EffectOutputCount() > 0) { | 2147 if (result->op()->EffectOutputCount() > 0) { |
| 2124 environment()->UpdateEffectDependency(result); | 2148 environment()->UpdateEffectDependency(result); |
| 2125 } | 2149 } |
| 2126 // Add implicit exception continuation for throwing nodes. | 2150 // Add implicit exception continuation for throwing nodes. |
| 2127 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) { | 2151 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) { |
| 2128 int handler_offset = exception_handlers_.top().handler_offset_; | 2152 int handler_offset = exception_handlers_.top().handler_offset_; |
| 2129 int context_index = exception_handlers_.top().context_register_; | 2153 int context_index = exception_handlers_.top().context_register_; |
| 2130 interpreter::Register context_register(context_index); | 2154 interpreter::Register context_register(context_index); |
| 2131 Environment* success_env = environment()->CopyForConditional(); | 2155 Environment* success_env = environment()->Copy(); |
| 2132 const Operator* op = common()->IfException(); | 2156 const Operator* op = common()->IfException(); |
| 2133 Node* effect = environment()->GetEffectDependency(); | 2157 Node* effect = environment()->GetEffectDependency(); |
| 2134 Node* on_exception = graph()->NewNode(op, effect, result); | 2158 Node* on_exception = graph()->NewNode(op, effect, result); |
| 2135 Node* context = environment()->LookupRegister(context_register); | 2159 Node* context = environment()->LookupRegister(context_register); |
| 2136 environment()->UpdateControlDependency(on_exception); | 2160 environment()->UpdateControlDependency(on_exception); |
| 2137 environment()->UpdateEffectDependency(on_exception); | 2161 environment()->UpdateEffectDependency(on_exception); |
| 2138 environment()->BindAccumulator(on_exception); | 2162 environment()->BindAccumulator(on_exception); |
| 2139 environment()->SetContext(context); | 2163 environment()->SetContext(context); |
| 2140 MergeIntoSuccessorEnvironment(handler_offset); | 2164 MergeIntoSuccessorEnvironment(handler_offset); |
| 2141 set_environment(success_env); | 2165 set_environment(success_env); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2236 it->source_position().ScriptOffset(), start_position_.InliningId())); | 2260 it->source_position().ScriptOffset(), start_position_.InliningId())); |
| 2237 it->Advance(); | 2261 it->Advance(); |
| 2238 } else { | 2262 } else { |
| 2239 DCHECK_GT(it->code_offset(), offset); | 2263 DCHECK_GT(it->code_offset(), offset); |
| 2240 } | 2264 } |
| 2241 } | 2265 } |
| 2242 | 2266 |
| 2243 } // namespace compiler | 2267 } // namespace compiler |
| 2244 } // namespace internal | 2268 } // namespace internal |
| 2245 } // namespace v8 | 2269 } // namespace v8 |
| OLD | NEW |