Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(471)

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 16888013: Revert "Initial implementation of on-stack replacement (OSR)." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/bit_vector.h"
10 #include "vm/code_descriptors.h" 9 #include "vm/code_descriptors.h"
11 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
12 #include "vm/flags.h" 11 #include "vm/flags.h"
13 #include "vm/flow_graph_compiler.h" 12 #include "vm/flow_graph_compiler.h"
14 #include "vm/il_printer.h" 13 #include "vm/il_printer.h"
15 #include "vm/intermediate_language.h" 14 #include "vm/intermediate_language.h"
16 #include "vm/longjump.h" 15 #include "vm/longjump.h"
17 #include "vm/object_store.h" 16 #include "vm/object_store.h"
18 #include "vm/os.h" 17 #include "vm/os.h"
19 #include "vm/parser.h" 18 #include "vm/parser.h"
(...skipping 17 matching lines...) Expand all
37 36
38 static const String& PrivateCoreLibName(const String& str) { 37 static const String& PrivateCoreLibName(const String& str) {
39 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 38 const Library& core_lib = Library::Handle(Library::CoreLibrary());
40 const String& private_name = String::ZoneHandle(core_lib.PrivateName(str)); 39 const String& private_name = String::ZoneHandle(core_lib.PrivateName(str));
41 return private_name; 40 return private_name;
42 } 41 }
43 42
44 43
45 FlowGraphBuilder::FlowGraphBuilder(ParsedFunction* parsed_function, 44 FlowGraphBuilder::FlowGraphBuilder(ParsedFunction* parsed_function,
46 const Array& ic_data_array, 45 const Array& ic_data_array,
47 InlineExitCollector* exit_collector, 46 InlineExitCollector* exit_collector)
48 intptr_t osr_id)
49 : parsed_function_(parsed_function), 47 : parsed_function_(parsed_function),
50 ic_data_array_(ic_data_array), 48 ic_data_array_(ic_data_array),
51 num_copied_params_(parsed_function->num_copied_params()), 49 num_copied_params_(parsed_function->num_copied_params()),
52 // All parameters are copied if any parameter is. 50 // All parameters are copied if any parameter is.
53 num_non_copied_params_((num_copied_params_ == 0) 51 num_non_copied_params_((num_copied_params_ == 0)
54 ? parsed_function->function().num_fixed_parameters() 52 ? parsed_function->function().num_fixed_parameters()
55 : 0), 53 : 0),
56 num_stack_locals_(parsed_function->num_stack_locals()), 54 num_stack_locals_(parsed_function->num_stack_locals()),
57 exit_collector_(exit_collector), 55 exit_collector_(exit_collector),
58 last_used_block_id_(0), // 0 is used for the graph entry. 56 last_used_block_id_(0), // 0 is used for the graph entry.
59 context_level_(0), 57 context_level_(0),
60 last_used_try_index_(CatchClauseNode::kInvalidTryIndex), 58 last_used_try_index_(CatchClauseNode::kInvalidTryIndex),
61 try_index_(CatchClauseNode::kInvalidTryIndex), 59 try_index_(CatchClauseNode::kInvalidTryIndex),
62 graph_entry_(NULL), 60 graph_entry_(NULL),
63 args_pushed_(0), 61 args_pushed_(0) { }
64 osr_id_(osr_id) { }
65 62
66 63
67 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) { 64 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) {
68 graph_entry_->AddCatchEntry(entry); 65 graph_entry_->AddCatchEntry(entry);
69 } 66 }
70 67
71 68
72 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) { 69 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) {
73 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1); 70 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1);
74 ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id()); 71 ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id());
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 467 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
471 true_exit->Goto(join); 468 true_exit->Goto(join);
472 false_exit->Goto(join); 469 false_exit->Goto(join);
473 exit_ = join; 470 exit_ = join;
474 ASSERT(true_fragment.temp_index() == false_fragment.temp_index()); 471 ASSERT(true_fragment.temp_index() == false_fragment.temp_index());
475 temp_index_ = true_fragment.temp_index(); 472 temp_index_ = true_fragment.temp_index();
476 } 473 }
477 } 474 }
478 475
479 476
480 void EffectGraphVisitor::TieLoop(intptr_t token_pos, 477 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment,
481 const TestGraphVisitor& test_fragment,
482 const EffectGraphVisitor& body_fragment) { 478 const EffectGraphVisitor& body_fragment) {
483 // We have: a test graph fragment with zero, one, or two available exits; 479 // We have: a test graph fragment with zero, one, or two available exits;
484 // and an effect graph fragment with zero or one available exits. We want 480 // and an effect graph fragment with zero or one available exits. We want
485 // to append the 'while loop' consisting of the test graph fragment as 481 // to append the 'while loop' consisting of the test graph fragment as
486 // condition and the effect graph fragment as body. 482 // condition and the effect graph fragment as body.
487 ASSERT(is_open()); 483 ASSERT(is_open());
488 484
489 // 1. Connect the body to the test if it is reachable, and if so record 485 // 1. Connect the body to the test if it is reachable, and if so record
490 // its exit (if any). 486 // its exit (if any).
491 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); 487 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor();
492 Instruction* body_exit = AppendFragment(body_entry, body_fragment); 488 Instruction* body_exit = AppendFragment(body_entry, body_fragment);
493 489
494 // 2. Connect the test to this graph, including the body if reachable and 490 // 2. Connect the test to this graph, including the body if reachable and
495 // using a fresh join node if the body is reachable and has an open exit. 491 // using a fresh join node if the body is reachable and has an open exit.
496 if (body_exit == NULL) { 492 if (body_exit == NULL) {
497 Append(test_fragment); 493 Append(test_fragment);
498 } else { 494 } else {
499 JoinEntryInstr* join = 495 JoinEntryInstr* join =
500 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 496 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
501 CheckStackOverflowInstr* check = 497 join->LinkTo(test_fragment.entry());
502 new CheckStackOverflowInstr(token_pos, true);
503 join->LinkTo(check);
504 check->LinkTo(test_fragment.entry());
505 Goto(join); 498 Goto(join);
506 body_exit->Goto(join); 499 body_exit->Goto(join);
507 } 500 }
508 501
509 // 3. Set the exit to the graph to be the false successor of the test, a 502 // 3. Set the exit to the graph to be the false successor of the test, a
510 // fresh target node 503 // fresh target node
504
511 exit_ = test_fragment.CreateFalseSuccessor(); 505 exit_ = test_fragment.CreateFalseSuccessor();
512 } 506 }
513 507
514 508
515 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { 509 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) {
516 owner_->add_args_pushed(1); 510 owner_->add_args_pushed(1);
517 PushArgumentInstr* result = new PushArgumentInstr(value); 511 PushArgumentInstr* result = new PushArgumentInstr(value);
518 AddInstruction(result); 512 AddInstruction(result);
519 return result; 513 return result;
520 } 514 }
(...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 // f) loop-exit-target 1595 // f) loop-exit-target
1602 // g) break-join (optional) 1596 // g) break-join (optional)
1603 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) { 1597 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) {
1604 TestGraphVisitor for_test(owner(), 1598 TestGraphVisitor for_test(owner(),
1605 temp_index(), 1599 temp_index(),
1606 node->condition()->token_pos()); 1600 node->condition()->token_pos());
1607 node->condition()->Visit(&for_test); 1601 node->condition()->Visit(&for_test);
1608 ASSERT(!for_test.is_empty()); // Language spec. 1602 ASSERT(!for_test.is_empty()); // Language spec.
1609 1603
1610 EffectGraphVisitor for_body(owner(), temp_index()); 1604 EffectGraphVisitor for_body(owner(), temp_index());
1605 for_body.AddInstruction(
1606 new CheckStackOverflowInstr(node->token_pos()));
1611 node->body()->Visit(&for_body); 1607 node->body()->Visit(&for_body);
1612 1608
1613 // Labels are set after body traversal. 1609 // Labels are set after body traversal.
1614 SourceLabel* lbl = node->label(); 1610 SourceLabel* lbl = node->label();
1615 ASSERT(lbl != NULL); 1611 ASSERT(lbl != NULL);
1616 JoinEntryInstr* join = lbl->join_for_continue(); 1612 JoinEntryInstr* join = lbl->join_for_continue();
1617 if (join != NULL) { 1613 if (join != NULL) {
1618 if (for_body.is_open()) for_body.Goto(join); 1614 if (for_body.is_open()) for_body.Goto(join);
1619 for_body.exit_ = join; 1615 for_body.exit_ = join;
1620 } 1616 }
1621 TieLoop(node->token_pos(), for_test, for_body); 1617 TieLoop(for_test, for_body);
1622 join = lbl->join_for_break(); 1618 join = lbl->join_for_break();
1623 if (join != NULL) { 1619 if (join != NULL) {
1624 Goto(join); 1620 Goto(join);
1625 exit_ = join; 1621 exit_ = join;
1626 } 1622 }
1627 } 1623 }
1628 1624
1629 1625
1630 // The fragment is composed as follows: 1626 // The fragment is composed as follows:
1631 // a) body-entry-join 1627 // a) body-entry-join
1632 // b) [ body ] 1628 // b) [ body ]
1633 // c) test-entry (continue-join or body-exit-target) 1629 // c) test-entry (continue-join or body-exit-target)
1634 // d) [ test-entry ] -> (back-target, loop-exit-target) 1630 // d) [ test-entry ] -> (back-target, loop-exit-target)
1635 // e) back-target -> (body-entry-join) 1631 // e) back-target -> (body-entry-join)
1636 // f) loop-exit-target 1632 // f) loop-exit-target
1637 // g) break-join 1633 // g) break-join
1638 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { 1634 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
1639 // Traverse body first in order to generate continue and break labels. 1635 // Traverse body first in order to generate continue and break labels.
1640 EffectGraphVisitor for_body(owner(), temp_index()); 1636 EffectGraphVisitor for_body(owner(), temp_index());
1637 for_body.AddInstruction(
1638 new CheckStackOverflowInstr(node->token_pos()));
1641 node->body()->Visit(&for_body); 1639 node->body()->Visit(&for_body);
1642 1640
1643 TestGraphVisitor for_test(owner(), 1641 TestGraphVisitor for_test(owner(),
1644 temp_index(), 1642 temp_index(),
1645 node->condition()->token_pos()); 1643 node->condition()->token_pos());
1646 node->condition()->Visit(&for_test); 1644 node->condition()->Visit(&for_test);
1647 ASSERT(is_open()); 1645 ASSERT(is_open());
1648 1646
1649 // Tie do-while loop (test is after the body). 1647 // Tie do-while loop (test is after the body).
1650 JoinEntryInstr* body_entry_join = 1648 JoinEntryInstr* body_entry_join =
1651 new JoinEntryInstr(owner()->AllocateBlockId(), 1649 new JoinEntryInstr(owner()->AllocateBlockId(),
1652 owner()->try_index()); 1650 owner()->try_index());
1653 Goto(body_entry_join); 1651 Goto(body_entry_join);
1654 Instruction* body_exit = AppendFragment(body_entry_join, for_body); 1652 Instruction* body_exit = AppendFragment(body_entry_join, for_body);
1655 1653
1656 JoinEntryInstr* join = node->label()->join_for_continue(); 1654 JoinEntryInstr* join = node->label()->join_for_continue();
1657 if ((body_exit != NULL) || (join != NULL)) { 1655 if ((body_exit != NULL) || (join != NULL)) {
1658 if (join == NULL) { 1656 if (join == NULL) {
1659 join = new JoinEntryInstr(owner()->AllocateBlockId(), 1657 join = new JoinEntryInstr(owner()->AllocateBlockId(),
1660 owner()->try_index()); 1658 owner()->try_index());
1661 } 1659 }
1662 CheckStackOverflowInstr* check = 1660 join->LinkTo(for_test.entry());
1663 new CheckStackOverflowInstr(node->token_pos(), true);
1664 join->LinkTo(check);
1665 check->LinkTo(for_test.entry());
1666 if (body_exit != NULL) { 1661 if (body_exit != NULL) {
1667 body_exit->Goto(join); 1662 body_exit->Goto(join);
1668 } 1663 }
1669 } 1664 }
1670 1665
1671 for_test.IfTrueGoto(body_entry_join); 1666 for_test.IfTrueGoto(body_entry_join);
1672 join = node->label()->join_for_break(); 1667 join = node->label()->join_for_break();
1673 if (join == NULL) { 1668 if (join == NULL) {
1674 exit_ = for_test.CreateFalseSuccessor(); 1669 exit_ = for_test.CreateFalseSuccessor();
1675 } else { 1670 } else {
(...skipping 16 matching lines...) Expand all
1692 // h) loop-exit-target 1687 // h) loop-exit-target
1693 // i) break-join 1688 // i) break-join
1694 void EffectGraphVisitor::VisitForNode(ForNode* node) { 1689 void EffectGraphVisitor::VisitForNode(ForNode* node) {
1695 EffectGraphVisitor for_initializer(owner(), temp_index()); 1690 EffectGraphVisitor for_initializer(owner(), temp_index());
1696 node->initializer()->Visit(&for_initializer); 1691 node->initializer()->Visit(&for_initializer);
1697 Append(for_initializer); 1692 Append(for_initializer);
1698 ASSERT(is_open()); 1693 ASSERT(is_open());
1699 1694
1700 // Compose body to set any jump labels. 1695 // Compose body to set any jump labels.
1701 EffectGraphVisitor for_body(owner(), temp_index()); 1696 EffectGraphVisitor for_body(owner(), temp_index());
1697 for_body.AddInstruction(
1698 new CheckStackOverflowInstr(node->token_pos()));
1702 node->body()->Visit(&for_body); 1699 node->body()->Visit(&for_body);
1703 1700
1701 // Join loop body, increment and compute their end instruction.
1702 ASSERT(!for_body.is_empty());
1703 Instruction* loop_increment_end = NULL;
1704 EffectGraphVisitor for_increment(owner(), temp_index()); 1704 EffectGraphVisitor for_increment(owner(), temp_index());
1705 node->increment()->Visit(&for_increment); 1705 node->increment()->Visit(&for_increment);
1706 JoinEntryInstr* join = node->label()->join_for_continue();
1707 if (join != NULL) {
1708 // Insert the join between the body and increment.
1709 if (for_body.is_open()) for_body.Goto(join);
1710 loop_increment_end = AppendFragment(join, for_increment);
1711 ASSERT(loop_increment_end != NULL);
1712 } else if (for_body.is_open()) {
1713 // Do not insert an extra basic block.
1714 for_body.Append(for_increment);
1715 loop_increment_end = for_body.exit();
1716 // 'for_body' contains at least the stack check.
1717 ASSERT(loop_increment_end != NULL);
1718 } else {
1719 loop_increment_end = NULL;
1720 }
1706 1721
1707 // Join the loop body and increment and then tie the loop. 1722 // 'loop_increment_end' is NULL only if there is no join for continue and the
1708 JoinEntryInstr* join = node->label()->join_for_continue(); 1723 // body is not open, i.e., no backward branch exists.
1709 if ((join != NULL) || for_body.is_open()) { 1724 if (loop_increment_end != NULL) {
1710 JoinEntryInstr* loop_start = 1725 JoinEntryInstr* loop_start =
1711 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 1726 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1712 if (join != NULL) {
1713 if (for_body.is_open()) for_body.Goto(join);
1714 AppendFragment(join, for_increment);
1715 for_increment.Goto(loop_start);
1716 } else {
1717 for_body.Append(for_increment);
1718 for_body.Goto(loop_start);
1719 }
1720 Goto(loop_start); 1727 Goto(loop_start);
1728 loop_increment_end->Goto(loop_start);
1721 exit_ = loop_start; 1729 exit_ = loop_start;
1722 AddInstruction(new CheckStackOverflowInstr(node->token_pos(), true));
1723 } 1730 }
1724 1731
1725 if (node->condition() == NULL) { 1732 if (node->condition() == NULL) {
1726 // Endless loop, no test. 1733 // Endless loop, no test.
1727 JoinEntryInstr* body_entry = 1734 JoinEntryInstr* body_entry =
1728 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 1735 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1729 AppendFragment(body_entry, for_body); 1736 AppendFragment(body_entry, for_body);
1730 Goto(body_entry); 1737 Goto(body_entry);
1731 if (node->label()->join_for_break() != NULL) { 1738 if (node->label()->join_for_break() != NULL) {
1732 // Control flow of ForLoop continues into join_for_break. 1739 // Control flow of ForLoop continues into join_for_break.
(...skipping 1715 matching lines...) Expand 10 before | Expand all | Expand 10 after
3448 AppendFragment(finally_entry, for_finally_block); 3455 AppendFragment(finally_entry, for_finally_block);
3449 exit_ = for_finally_block.exit_; 3456 exit_ = for_finally_block.exit_;
3450 } 3457 }
3451 3458
3452 3459
3453 FlowGraph* FlowGraphBuilder::BuildGraph() { 3460 FlowGraph* FlowGraphBuilder::BuildGraph() {
3454 if (FLAG_print_ast) { 3461 if (FLAG_print_ast) {
3455 // Print the function ast before IL generation. 3462 // Print the function ast before IL generation.
3456 AstPrinter::PrintFunctionNodes(*parsed_function()); 3463 AstPrinter::PrintFunctionNodes(*parsed_function());
3457 } 3464 }
3465 // Compilation can be nested, preserve the computation-id.
3458 const Function& function = parsed_function()->function(); 3466 const Function& function = parsed_function()->function();
3459 TargetEntryInstr* normal_entry = 3467 TargetEntryInstr* normal_entry =
3460 new TargetEntryInstr(AllocateBlockId(), 3468 new TargetEntryInstr(AllocateBlockId(),
3461 CatchClauseNode::kInvalidTryIndex); 3469 CatchClauseNode::kInvalidTryIndex);
3462 graph_entry_ = new GraphEntryInstr(*parsed_function(), normal_entry, osr_id_); 3470 graph_entry_ = new GraphEntryInstr(*parsed_function(), normal_entry);
3463 EffectGraphVisitor for_effect(this, 0); 3471 EffectGraphVisitor for_effect(this, 0);
3464 // This check may be deleted if the generated code is leaf. 3472 // This check may be deleted if the generated code is leaf.
3465 CheckStackOverflowInstr* check = 3473 CheckStackOverflowInstr* check =
3466 new CheckStackOverflowInstr(function.token_pos(), false); 3474 new CheckStackOverflowInstr(function.token_pos());
3467 // If we are inlining don't actually attach the stack check. We must still 3475 // If we are inlining don't actually attach the stack check. We must still
3468 // create the stack check in order to allocate a deopt id. 3476 // create the stack check in order to allocate a deopt id.
3469 if (!IsInlining()) for_effect.AddInstruction(check); 3477 if (!IsInlining()) for_effect.AddInstruction(check);
3470 parsed_function()->node_sequence()->Visit(&for_effect); 3478 parsed_function()->node_sequence()->Visit(&for_effect);
3471 AppendFragment(normal_entry, for_effect); 3479 AppendFragment(normal_entry, for_effect);
3472 // Check that the graph is properly terminated. 3480 // Check that the graph is properly terminated.
3473 ASSERT(!for_effect.is_open()); 3481 ASSERT(!for_effect.is_open());
3474
3475 // When compiling for OSR, use a depth first search to prune instructions
3476 // unreachable from the OSR entry. Catch entries are not (yet) properly
3477 // recognized as reachable.
3478 if (osr_id_ != Isolate::kNoDeoptId) {
3479 if (graph_entry_->SuccessorCount() > 1) {
3480 Bailout("try/catch when compiling for OSR");
3481 }
3482 PruneUnreachable();
3483 }
3484
3485 FlowGraph* graph = new FlowGraph(*this, graph_entry_, last_used_block_id_); 3482 FlowGraph* graph = new FlowGraph(*this, graph_entry_, last_used_block_id_);
3486 return graph; 3483 return graph;
3487 } 3484 }
3488 3485
3489 3486
3490 void FlowGraphBuilder::PruneUnreachable() {
3491 ASSERT(osr_id_ != Isolate::kNoDeoptId);
3492 BitVector* block_marks = new BitVector(last_used_block_id_ + 1);
3493 bool found = graph_entry_->PruneUnreachable(this, graph_entry_, osr_id_,
3494 block_marks);
3495 ASSERT(found);
3496 }
3497
3498
3499 void FlowGraphBuilder::Bailout(const char* reason) { 3487 void FlowGraphBuilder::Bailout(const char* reason) {
3500 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; 3488 const char* kFormat = "FlowGraphBuilder Bailout: %s %s";
3501 const char* function_name = parsed_function_->function().ToCString(); 3489 const char* function_name = parsed_function_->function().ToCString();
3502 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 3490 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
3503 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 3491 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
3504 OS::SNPrint(chars, len, kFormat, function_name, reason); 3492 OS::SNPrint(chars, len, kFormat, function_name, reason);
3505 const Error& error = Error::Handle( 3493 const Error& error = Error::Handle(
3506 LanguageError::New(String::Handle(String::New(chars)))); 3494 LanguageError::New(String::Handle(String::New(chars))));
3507 Isolate::Current()->long_jump_base()->Jump(1, error); 3495 Isolate::Current()->long_jump_base()->Jump(1, error);
3508 } 3496 }
3509 3497
3510 3498
3511 } // namespace dart 3499 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698