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

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

Issue 10891025: Eliminate class UseVal. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 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
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.h" 5 #include "vm/flow_graph.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/flow_graph_builder.h" 8 #include "vm/flow_graph_builder.h"
9 #include "vm/intermediate_language.h" 9 #include "vm/intermediate_language.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 current->set_previous(previous); 60 current->set_previous(previous);
61 previous = current; 61 previous = current;
62 } 62 }
63 } 63 }
64 } 64 }
65 65
66 66
67 #ifdef DEBUG 67 #ifdef DEBUG
68 // Debugging code to verify the construction of use lists. 68 // Debugging code to verify the construction of use lists.
69 69
70 static intptr_t MembershipCount(UseVal* use, UseVal* list) { 70 static intptr_t MembershipCount(Value* use, Value* list) {
71 intptr_t count = 0; 71 intptr_t count = 0;
72 while (list != NULL) { 72 while (list != NULL) {
73 if (list == use) ++count; 73 if (list == use) ++count;
74 list = list->next_use(); 74 list = list->next_use();
75 } 75 }
76 return count; 76 return count;
77 } 77 }
78 78
79 79
80 static void ResetUseListsInInstruction(Instruction* instr) { 80 static void ResetUseListsInInstruction(Instruction* instr) {
81 Definition* defn = instr->AsDefinition(); 81 Definition* defn = instr->AsDefinition();
82 if (defn != NULL) { 82 if (defn != NULL) {
83 defn->set_input_use_list(NULL); 83 defn->set_input_use_list(NULL);
84 defn->set_env_use_list(NULL); 84 defn->set_env_use_list(NULL);
85 } 85 }
86 for (intptr_t i = 0; i < instr->InputCount(); ++i) { 86 for (intptr_t i = 0; i < instr->InputCount(); ++i) {
87 UseVal* use = instr->InputAt(i)->AsUse(); 87 Value* use = instr->InputAt(i);
88 if (use == NULL) continue;
89 use->set_instruction(NULL); 88 use->set_instruction(NULL);
90 use->set_use_index(-1); 89 use->set_use_index(-1);
91 use->set_next_use(NULL); 90 use->set_next_use(NULL);
92 } 91 }
93 if (instr->env() != NULL) { 92 if (instr->env() != NULL) {
94 for (intptr_t i = 0; i < instr->env()->values().length(); ++i) { 93 for (intptr_t i = 0; i < instr->env()->values().length(); ++i) {
95 UseVal* use = instr->env()->values()[i]->AsUse(); 94 Value* use = instr->env()->values()[i];
96 if (use == NULL) continue;
97 use->set_instruction(NULL); 95 use->set_instruction(NULL);
98 use->set_use_index(-1); 96 use->set_use_index(-1);
99 use->set_next_use(NULL); 97 use->set_next_use(NULL);
100 } 98 }
101 } 99 }
102 } 100 }
103 101
104 102
105 bool FlowGraph::ResetUseLists() { 103 bool FlowGraph::ResetUseLists() {
106 // Reset global constants. 104 // Reset global constants.
107 ResetUseListsInInstruction(graph_entry_->constant_null()); 105 ResetUseListsInInstruction(graph_entry_->constant_null());
108 106
109 // Reset definitions referenced from the start environment. 107 // Reset definitions referenced from the start environment.
110 for (intptr_t i = 0; i < graph_entry_->start_env()->values().length(); ++i) { 108 for (intptr_t i = 0; i < graph_entry_->start_env()->values().length(); ++i) {
111 UseVal* env_use = graph_entry_->start_env()->values()[i]->AsUse(); 109 Value* env_use = graph_entry_->start_env()->values()[i];
112 if (env_use != NULL) ResetUseListsInInstruction(env_use->definition()); 110 ResetUseListsInInstruction(env_use->definition());
113 } 111 }
114 112
115 // Reset phis in join entries and the instructions in each block. 113 // Reset phis in join entries and the instructions in each block.
116 for (intptr_t i = 0; i < preorder_.length(); ++i) { 114 for (intptr_t i = 0; i < preorder_.length(); ++i) {
117 BlockEntryInstr* entry = preorder_[i]; 115 BlockEntryInstr* entry = preorder_[i];
118 JoinEntryInstr* join = entry->AsJoinEntry(); 116 JoinEntryInstr* join = entry->AsJoinEntry();
119 if (join != NULL && join->phis() != NULL) { 117 if (join != NULL && join->phis() != NULL) {
120 for (intptr_t i = 0; i < join->phis()->length(); ++i) { 118 for (intptr_t i = 0; i < join->phis()->length(); ++i) {
121 PhiInstr* phi = (*join->phis())[i]; 119 PhiInstr* phi = (*join->phis())[i];
122 if (phi != NULL) ResetUseListsInInstruction(phi); 120 if (phi != NULL) ResetUseListsInInstruction(phi);
123 } 121 }
124 } 122 }
125 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { 123 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
126 ResetUseListsInInstruction(it.Current()); 124 ResetUseListsInInstruction(it.Current());
127 } 125 }
128 } 126 }
129 return true; // Return true so we can ASSERT the reset code. 127 return true; // Return true so we can ASSERT the reset code.
130 } 128 }
131 129
132 130
133 static void ValidateUseListsInInstruction(Instruction* instr) { 131 static void ValidateUseListsInInstruction(Instruction* instr) {
134 ASSERT(instr != NULL); 132 ASSERT(instr != NULL);
135 ASSERT(!instr->IsJoinEntry()); 133 ASSERT(!instr->IsJoinEntry());
136 for (intptr_t i = 0; i < instr->InputCount(); ++i) { 134 for (intptr_t i = 0; i < instr->InputCount(); ++i) {
137 UseVal* use = instr->InputAt(i)->AsUse(); 135 Value* use = instr->InputAt(i);
138 if (use == NULL) continue;
139 ASSERT(use->use_index() == i); 136 ASSERT(use->use_index() == i);
140 ASSERT(1 == MembershipCount(use, use->definition()->input_use_list())); 137 ASSERT(1 == MembershipCount(use, use->definition()->input_use_list()));
141 } 138 }
142 Environment* env = instr->env(); 139 Environment* env = instr->env();
143 if (env != NULL) { 140 if (env != NULL) {
144 for (intptr_t i = 0; i < env->values().length(); ++i) { 141 for (intptr_t i = 0; i < env->values().length(); ++i) {
145 UseVal* use = env->values()[i]->AsUse(); 142 Value* use = env->values()[i];
146 if (use == NULL) continue;
147 ASSERT(use->use_index() == i); 143 ASSERT(use->use_index() == i);
148 ASSERT(1 == MembershipCount(use, use->definition()->env_use_list())); 144 ASSERT(1 == MembershipCount(use, use->definition()->env_use_list()));
149 } 145 }
150 } 146 }
151 Definition* defn = instr->AsDefinition(); 147 Definition* defn = instr->AsDefinition();
152 if (defn != NULL) { 148 if (defn != NULL) {
153 for (UseVal* use = defn->input_use_list(); 149 for (Value* use = defn->input_use_list();
154 use != NULL; 150 use != NULL;
155 use = use->next_use()) { 151 use = use->next_use()) {
156 ASSERT(defn == use->definition()); 152 ASSERT(defn == use->definition());
157 ASSERT(use == use->instruction()->InputAt(use->use_index())); 153 ASSERT(use == use->instruction()->InputAt(use->use_index()));
158 } 154 }
159 for (UseVal* use = defn->env_use_list(); 155 for (Value* use = defn->env_use_list();
160 use != NULL; 156 use != NULL;
161 use = use->next_use()) { 157 use = use->next_use()) {
162 ASSERT(defn == use->definition()); 158 ASSERT(defn == use->definition());
163 ASSERT(use == use->instruction()->env()->values()[use->use_index()]); 159 ASSERT(use == use->instruction()->env()->values()[use->use_index()]);
164 } 160 }
165 } 161 }
166 } 162 }
167 163
168 164
169 bool FlowGraph::ValidateUseLists() { 165 bool FlowGraph::ValidateUseLists() {
170 // Validate global constants. 166 // Validate global constants.
171 ValidateUseListsInInstruction(graph_entry_->constant_null()); 167 ValidateUseListsInInstruction(graph_entry_->constant_null());
172 168
173 // Validate definitions referenced from the start environment. 169 // Validate definitions referenced from the start environment.
174 for (intptr_t i = 0; i < graph_entry_->start_env()->values().length(); ++i) { 170 for (intptr_t i = 0; i < graph_entry_->start_env()->values().length(); ++i) {
175 UseVal* env_use = graph_entry_->start_env()->values()[i]->AsUse(); 171 Value* env_use = graph_entry_->start_env()->values()[i];
176 if (env_use != NULL) ValidateUseListsInInstruction(env_use->definition()); 172 ValidateUseListsInInstruction(env_use->definition());
177 } 173 }
178 174
179 // Validate phis in join entries and the instructions in each block. 175 // Validate phis in join entries and the instructions in each block.
180 for (intptr_t i = 0; i < preorder_.length(); ++i) { 176 for (intptr_t i = 0; i < preorder_.length(); ++i) {
181 BlockEntryInstr* entry = preorder_[i]; 177 BlockEntryInstr* entry = preorder_[i];
182 JoinEntryInstr* join = entry->AsJoinEntry(); 178 JoinEntryInstr* join = entry->AsJoinEntry();
183 if (join != NULL && join->phis() != NULL) { 179 if (join != NULL && join->phis() != NULL) {
184 for (intptr_t i = 0; i < join->phis()->length(); ++i) { 180 for (intptr_t i = 0; i < join->phis()->length(); ++i) {
185 PhiInstr* phi = (*join->phis())[i]; 181 PhiInstr* phi = (*join->phis())[i];
186 if (phi != NULL) ValidateUseListsInInstruction(phi); 182 if (phi != NULL) ValidateUseListsInInstruction(phi);
(...skipping 13 matching lines...) Expand all
200 DEBUG_ASSERT(defn->input_use_list() == NULL); 196 DEBUG_ASSERT(defn->input_use_list() == NULL);
201 DEBUG_ASSERT(defn->env_use_list() == NULL); 197 DEBUG_ASSERT(defn->env_use_list() == NULL);
202 defn->set_input_use_list(NULL); 198 defn->set_input_use_list(NULL);
203 defn->set_env_use_list(NULL); 199 defn->set_env_use_list(NULL);
204 } 200 }
205 201
206 202
207 static void RecordInputUses(Instruction* instr) { 203 static void RecordInputUses(Instruction* instr) {
208 ASSERT(instr != NULL); 204 ASSERT(instr != NULL);
209 for (intptr_t i = 0; i < instr->InputCount(); ++i) { 205 for (intptr_t i = 0; i < instr->InputCount(); ++i) {
210 UseVal* use = instr->InputAt(i)->AsUse(); 206 Value* use = instr->InputAt(i);
211 if (use == NULL) continue;
212 DEBUG_ASSERT(use->instruction() == NULL); 207 DEBUG_ASSERT(use->instruction() == NULL);
213 DEBUG_ASSERT(use->use_index() == -1); 208 DEBUG_ASSERT(use->use_index() == -1);
214 DEBUG_ASSERT(use->next_use() == NULL); 209 DEBUG_ASSERT(use->next_use() == NULL);
215 DEBUG_ASSERT(0 == MembershipCount(use, 210 DEBUG_ASSERT(0 == MembershipCount(use,
216 use->definition()->input_use_list())); 211 use->definition()->input_use_list()));
217 use->set_instruction(instr); 212 use->set_instruction(instr);
218 use->set_use_index(i); 213 use->set_use_index(i);
219 use->AddToInputUseList(); 214 use->AddToInputUseList();
220 } 215 }
221 } 216 }
222 217
223 218
224 static void RecordEnvUses(Instruction* instr) { 219 static void RecordEnvUses(Instruction* instr) {
225 ASSERT(instr != NULL); 220 ASSERT(instr != NULL);
226 if (instr->env() == NULL) return; 221 if (instr->env() == NULL) return;
227 for (intptr_t i = 0; i < instr->env()->values().length(); ++i) { 222 for (intptr_t i = 0; i < instr->env()->values().length(); ++i) {
228 UseVal* use = instr->env()->values()[i]->AsUse(); 223 Value* use = instr->env()->values()[i];
229 if (use == NULL) continue;
230 DEBUG_ASSERT(use->instruction() == NULL); 224 DEBUG_ASSERT(use->instruction() == NULL);
231 DEBUG_ASSERT(use->use_index() == -1); 225 DEBUG_ASSERT(use->use_index() == -1);
232 DEBUG_ASSERT(use->next_use() == NULL); 226 DEBUG_ASSERT(use->next_use() == NULL);
233 DEBUG_ASSERT(0 == MembershipCount(use, use->definition()->env_use_list())); 227 DEBUG_ASSERT(0 == MembershipCount(use, use->definition()->env_use_list()));
234 use->set_instruction(instr); 228 use->set_instruction(instr);
235 use->set_use_index(i); 229 use->set_use_index(i);
236 use->AddToEnvUseList(); 230 use->AddToEnvUseList();
237 } 231 }
238 } 232 }
239 233
(...skipping 22 matching lines...) Expand all
262 if (block->last_instruction()->SuccessorCount() == 1 && 256 if (block->last_instruction()->SuccessorCount() == 1 &&
263 block->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { 257 block->last_instruction()->SuccessorAt(0)->IsJoinEntry()) {
264 JoinEntryInstr* join = 258 JoinEntryInstr* join =
265 block->last_instruction()->SuccessorAt(0)->AsJoinEntry(); 259 block->last_instruction()->SuccessorAt(0)->AsJoinEntry();
266 intptr_t pred_index = join->IndexOfPredecessor(block); 260 intptr_t pred_index = join->IndexOfPredecessor(block);
267 ASSERT(pred_index >= 0); 261 ASSERT(pred_index >= 0);
268 if (join->phis() != NULL) { 262 if (join->phis() != NULL) {
269 for (intptr_t i = 0; i < join->phis()->length(); ++i) { 263 for (intptr_t i = 0; i < join->phis()->length(); ++i) {
270 PhiInstr* phi = (*join->phis())[i]; 264 PhiInstr* phi = (*join->phis())[i];
271 if (phi == NULL) continue; 265 if (phi == NULL) continue;
272 UseVal* use = phi->InputAt(pred_index)->AsUse(); 266 Value* use = phi->InputAt(pred_index);
273 if (use == NULL) continue;
274 DEBUG_ASSERT(use->instruction() == NULL); 267 DEBUG_ASSERT(use->instruction() == NULL);
275 DEBUG_ASSERT(use->use_index() == -1); 268 DEBUG_ASSERT(use->use_index() == -1);
276 DEBUG_ASSERT(use->next_use() == NULL); 269 DEBUG_ASSERT(use->next_use() == NULL);
277 DEBUG_ASSERT(0 == MembershipCount(use, 270 DEBUG_ASSERT(0 == MembershipCount(use,
278 use->definition()->input_use_list())); 271 use->definition()->input_use_list()));
279 use->set_instruction(phi); 272 use->set_instruction(phi);
280 use->set_use_index(pred_index); 273 use->set_use_index(pred_index);
281 use->AddToInputUseList(); 274 use->AddToInputUseList();
282 } 275 }
283 } 276 }
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 // gets a full copy of the environment. Later we optimize this by 534 // gets a full copy of the environment. Later we optimize this by
542 // eliminating unnecessary environments. 535 // eliminating unnecessary environments.
543 current->set_env(new Environment(*env, non_copied_parameter_count_)); 536 current->set_env(new Environment(*env, non_copied_parameter_count_));
544 537
545 // 2a. Handle uses: 538 // 2a. Handle uses:
546 // Update expression stack environment for each use. 539 // Update expression stack environment for each use.
547 // For each use of a LoadLocal or StoreLocal: Replace it with the value 540 // For each use of a LoadLocal or StoreLocal: Replace it with the value
548 // from the environment. 541 // from the environment.
549 for (intptr_t i = current->InputCount() - 1; i >= 0; --i) { 542 for (intptr_t i = current->InputCount() - 1; i >= 0; --i) {
550 Value* v = current->InputAt(i); 543 Value* v = current->InputAt(i);
551 if (!v->IsUse()) continue;
552 // Update expression stack. 544 // Update expression stack.
553 ASSERT(env->length() > variable_count()); 545 ASSERT(env->length() > variable_count());
554 546
555 Definition* input_defn = env->Last(); 547 Definition* input_defn = env->Last();
556 env->RemoveLast(); 548 env->RemoveLast();
557 549
558 BindInstr* as_bind = v->AsUse()->definition()->AsBind(); 550 BindInstr* as_bind = v->definition()->AsBind();
559 if ((as_bind != NULL) && 551 if ((as_bind != NULL) &&
560 (as_bind->computation()->IsLoadLocal() || 552 (as_bind->computation()->IsLoadLocal() ||
561 as_bind->computation()->IsStoreLocal())) { 553 as_bind->computation()->IsStoreLocal())) {
562 // Remove the load/store from the graph. 554 // Remove the load/store from the graph.
563 as_bind->RemoveFromGraph(); 555 as_bind->RemoveFromGraph();
564 // Assert we are not referencing nulls in the initial environment. 556 // Assert we are not referencing nulls in the initial environment.
565 ASSERT(input_defn->ssa_temp_index() != -1); 557 ASSERT(input_defn->ssa_temp_index() != -1);
566 current->SetInputAt(i, new UseVal(input_defn)); 558 current->SetInputAt(i, new Value(input_defn));
567 } 559 }
568 } 560 }
569 561
570 // Drop pushed arguments for calls. 562 // Drop pushed arguments for calls.
571 for (intptr_t j = 0; j < current->ArgumentCount(); j++) { 563 for (intptr_t j = 0; j < current->ArgumentCount(); j++) {
572 env->RemoveLast(); 564 env->RemoveLast();
573 } 565 }
574 566
575 // 2b. Handle LoadLocal and StoreLocal. 567 // 2b. Handle LoadLocal and StoreLocal.
576 // For each LoadLocal: Remove it from the graph. 568 // For each LoadLocal: Remove it from the graph.
577 // For each StoreLocal: Remove it from the graph and update the environment. 569 // For each StoreLocal: Remove it from the graph and update the environment.
578 BindInstr* bind = current->AsBind(); 570 BindInstr* bind = current->AsBind();
579 if (bind != NULL) { 571 if (bind != NULL) {
580 LoadLocalComp* load = bind->computation()->AsLoadLocal(); 572 LoadLocalComp* load = bind->computation()->AsLoadLocal();
581 StoreLocalComp* store = bind->computation()->AsStoreLocal(); 573 StoreLocalComp* store = bind->computation()->AsStoreLocal();
582 if ((load != NULL) || (store != NULL)) { 574 if ((load != NULL) || (store != NULL)) {
583 intptr_t index; 575 intptr_t index;
584 if (store != NULL) { 576 if (store != NULL) {
585 index = store->local().BitIndexIn(non_copied_parameter_count_); 577 index = store->local().BitIndexIn(non_copied_parameter_count_);
586 // Update renaming environment. 578 // Update renaming environment.
587 ASSERT(store->value()->IsUse()); 579 (*env)[index] = store->value()->definition();
588 (*env)[index] = store->value()->AsUse()->definition();
589 } else { 580 } else {
590 // The graph construction ensures we do not have an unused LoadLocal 581 // The graph construction ensures we do not have an unused LoadLocal
591 // computation. 582 // computation.
592 ASSERT(bind->is_used()); 583 ASSERT(bind->is_used());
593 index = load->local().BitIndexIn(non_copied_parameter_count_); 584 index = load->local().BitIndexIn(non_copied_parameter_count_);
594 585
595 PhiInstr* phi = (*env)[index]->AsPhi(); 586 PhiInstr* phi = (*env)[index]->AsPhi();
596 if ((phi != NULL) && !phi->is_alive()) { 587 if ((phi != NULL) && !phi->is_alive()) {
597 phi->mark_alive(); 588 phi->mark_alive();
598 live_phis->Add(phi); 589 live_phis->Add(phi);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { 627 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) {
637 JoinEntryInstr* successor = 628 JoinEntryInstr* successor =
638 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry(); 629 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry();
639 intptr_t pred_index = successor->IndexOfPredecessor(block_entry); 630 intptr_t pred_index = successor->IndexOfPredecessor(block_entry);
640 ASSERT(pred_index >= 0); 631 ASSERT(pred_index >= 0);
641 if (successor->phis() != NULL) { 632 if (successor->phis() != NULL) {
642 for (intptr_t i = 0; i < successor->phis()->length(); ++i) { 633 for (intptr_t i = 0; i < successor->phis()->length(); ++i) {
643 PhiInstr* phi = (*successor->phis())[i]; 634 PhiInstr* phi = (*successor->phis())[i];
644 if (phi != NULL) { 635 if (phi != NULL) {
645 // Rename input operand. 636 // Rename input operand.
646 phi->SetInputAt(pred_index, new UseVal((*env)[i])); 637 phi->SetInputAt(pred_index, new Value((*env)[i]));
647 } 638 }
648 } 639 }
649 } 640 }
650 } 641 }
651 } 642 }
652 643
653 644
654 void FlowGraph::MarkLivePhis(GrowableArray<PhiInstr*>* live_phis) { 645 void FlowGraph::MarkLivePhis(GrowableArray<PhiInstr*>* live_phis) {
655 while (!live_phis->is_empty()) { 646 while (!live_phis->is_empty()) {
656 PhiInstr* phi = live_phis->Last(); 647 PhiInstr* phi = live_phis->Last();
657 live_phis->RemoveLast(); 648 live_phis->RemoveLast();
658 for (intptr_t i = 0; i < phi->InputCount(); i++) { 649 for (intptr_t i = 0; i < phi->InputCount(); i++) {
659 Value* val = phi->InputAt(i); 650 Value* val = phi->InputAt(i);
660 if (!val->IsUse()) continue; 651 PhiInstr* used_phi = val->definition()->AsPhi();
661 PhiInstr* used_phi = val->AsUse()->definition()->AsPhi();
662 if ((used_phi != NULL) && !used_phi->is_alive()) { 652 if ((used_phi != NULL) && !used_phi->is_alive()) {
663 used_phi->mark_alive(); 653 used_phi->mark_alive();
664 live_phis->Add(used_phi); 654 live_phis->Add(used_phi);
665 } 655 }
666 } 656 }
667 } 657 }
668 } 658 }
669 659
670 660
671 void FlowGraph::Bailout(const char* reason) const { 661 void FlowGraph::Bailout(const char* reason) const {
672 const char* kFormat = "FlowGraph Bailout: %s %s"; 662 const char* kFormat = "FlowGraph Bailout: %s %s";
673 const char* function_name = parsed_function_.function().ToCString(); 663 const char* function_name = parsed_function_.function().ToCString();
674 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 664 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
675 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 665 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
676 OS::SNPrint(chars, len, kFormat, function_name, reason); 666 OS::SNPrint(chars, len, kFormat, function_name, reason);
677 const Error& error = Error::Handle( 667 const Error& error = Error::Handle(
678 LanguageError::New(String::Handle(String::New(chars)))); 668 LanguageError::New(String::Handle(String::New(chars))));
679 Isolate::Current()->long_jump_base()->Jump(1, error); 669 Isolate::Current()->long_jump_base()->Jump(1, error);
680 } 670 }
681 671
682 672
683 } // namespace dart 673 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698