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

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

Issue 10316005: Automatically assign temporary indices to definitions in the IL. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 7 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/intermediate_language.h » ('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 "vm/ast_printer.h" 7 #include "vm/ast_printer.h"
8 #include "vm/code_descriptors.h" 8 #include "vm/code_descriptors.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flags.h" 10 #include "vm/flags.h"
(...skipping 30 matching lines...) Expand all
41 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { 41 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) {
42 ASSERT(is_open()); 42 ASSERT(is_open());
43 if (other_fragment.is_empty()) return; 43 if (other_fragment.is_empty()) return;
44 if (is_empty()) { 44 if (is_empty()) {
45 entry_ = other_fragment.entry(); 45 entry_ = other_fragment.entry();
46 exit_ = other_fragment.exit(); 46 exit_ = other_fragment.exit();
47 } else { 47 } else {
48 exit()->SetSuccessor(other_fragment.entry()); 48 exit()->SetSuccessor(other_fragment.entry());
49 exit_ = other_fragment.exit(); 49 exit_ = other_fragment.exit();
50 } 50 }
51 temp_index_ = other_fragment.temp_index();
51 } 52 }
52 53
53 54
54 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { 55 void EffectGraphVisitor::AddInstruction(Instruction* instruction) {
55 ASSERT(is_open()); 56 ASSERT(is_open());
57 DeallocateTempIndex(instruction->InputCount());
58 if (instruction->IsDefinition()) {
59 instruction->AsDefinition()->set_temp_index(AllocateTempIndex());
60 }
56 if (is_empty()) { 61 if (is_empty()) {
57 entry_ = exit_ = instruction; 62 entry_ = exit_ = instruction;
58 } else { 63 } else {
59 exit()->SetSuccessor(instruction); 64 exit()->SetSuccessor(instruction);
60 exit_ = instruction; 65 exit_ = instruction;
61 } 66 }
62 } 67 }
63 68
64 69
65 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment, 70 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment,
(...skipping 18 matching lines...) Expand all
84 true_exit = true_fragment.is_empty() ? true_entry : true_fragment.exit(); 89 true_exit = true_fragment.is_empty() ? true_entry : true_fragment.exit();
85 90
86 TargetEntryInstr* false_entry = new TargetEntryInstr(); 91 TargetEntryInstr* false_entry = new TargetEntryInstr();
87 *test_fragment.false_successor_address() = false_entry; 92 *test_fragment.false_successor_address() = false_entry;
88 false_entry->SetSuccessor(false_fragment.entry()); 93 false_entry->SetSuccessor(false_fragment.entry());
89 false_exit = false_fragment.is_empty() ? false_entry : false_fragment.exit(); 94 false_exit = false_fragment.is_empty() ? false_entry : false_fragment.exit();
90 95
91 // 3. Add a join or select one (or neither) of the arms as exit. 96 // 3. Add a join or select one (or neither) of the arms as exit.
92 if (true_exit == NULL) { 97 if (true_exit == NULL) {
93 exit_ = false_exit; // May be NULL. 98 exit_ = false_exit; // May be NULL.
99 if (false_exit != NULL) temp_index_ = false_fragment.temp_index();
94 } else if (false_exit == NULL) { 100 } else if (false_exit == NULL) {
95 exit_ = true_exit; 101 exit_ = true_exit;
102 temp_index_ = true_fragment.temp_index();
96 } else { 103 } else {
97 exit_ = new JoinEntryInstr(); 104 exit_ = new JoinEntryInstr();
98 true_exit->SetSuccessor(exit_); 105 true_exit->SetSuccessor(exit_);
99 false_exit->SetSuccessor(exit_); 106 false_exit->SetSuccessor(exit_);
107 ASSERT(true_fragment.temp_index() == false_fragment.temp_index());
108 temp_index_ = true_fragment.temp_index();
100 } 109 }
101 } 110 }
102 111
103 112
104 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment, 113 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment,
105 const EffectGraphVisitor& body_fragment) { 114 const EffectGraphVisitor& body_fragment) {
106 // We have: a test graph fragment with zero, one, or two available exits; 115 // We have: a test graph fragment with zero, one, or two available exits;
107 // and an effect graph fragment with zero or one available exits. We want 116 // and an effect graph fragment with zero or one available exits. We want
108 // to append the 'while loop' consisting of the test graph fragment as 117 // to append the 'while loop' consisting of the test graph fragment as
109 // condition and the effect graph fragment as body. 118 // condition and the effect graph fragment as body.
(...skipping 19 matching lines...) Expand all
129 } 138 }
130 139
131 // 3. Set the exit to the graph to be the false successor of the test, a 140 // 3. Set the exit to the graph to be the false successor of the test, a
132 // fresh target node 141 // fresh target node
133 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr(); 142 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr();
134 } 143 }
135 144
136 145
137 // Stores current context into the 'variable' 146 // Stores current context into the 'variable'
138 void EffectGraphVisitor::BuildStoreContext(const LocalVariable& variable) { 147 void EffectGraphVisitor::BuildStoreContext(const LocalVariable& variable) {
139 BindInstr* context = new BindInstr(temp_index(), new CurrentContextComp()); 148 BindInstr* context = new BindInstr(new CurrentContextComp());
140 AddInstruction(context); 149 AddInstruction(context);
141 StoreLocalComp* store_context = 150 StoreLocalComp* store_context =
142 new StoreLocalComp(variable, new UseVal(context), 151 new StoreLocalComp(variable, new UseVal(context),
143 owner()->context_level()); 152 owner()->context_level());
144 AddInstruction(new DoInstr(store_context)); 153 AddInstruction(new DoInstr(store_context));
145 } 154 }
146 155
147 156
148 // Loads context saved in 'context_variable' into the current context. 157 // Loads context saved in 'context_variable' into the current context.
149 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) { 158 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) {
150 BindInstr* load_saved_context = 159 BindInstr* load_saved_context =
151 new BindInstr(temp_index(), 160 new BindInstr(new LoadLocalComp(variable, owner()->context_level()));
152 new LoadLocalComp(variable, owner()->context_level()));
153 AddInstruction(load_saved_context); 161 AddInstruction(load_saved_context);
154 DoInstr* store_context = 162 DoInstr* store_context =
155 new DoInstr(new StoreContextComp(new UseVal(load_saved_context))); 163 new DoInstr(new StoreContextComp(new UseVal(load_saved_context)));
156 AddInstruction(store_context); 164 AddInstruction(store_context);
157 } 165 }
158 166
159 167
160 168
161 void TestGraphVisitor::ReturnValue(Value* value) { 169 void TestGraphVisitor::ReturnValue(Value* value) {
162 if (FLAG_enable_type_checks) { 170 if (FLAG_enable_type_checks) {
163 BindInstr* assert_boolean = 171 BindInstr* assert_boolean =
164 new BindInstr(temp_index(), 172 new BindInstr(new AssertBooleanComp(condition_token_index(),
165 new AssertBooleanComp(condition_token_index(),
166 owner()->try_index(), 173 owner()->try_index(),
167 value)); 174 value));
168 AddInstruction(assert_boolean); 175 AddInstruction(assert_boolean);
169 value = new UseVal(assert_boolean); 176 value = new UseVal(assert_boolean);
170 } 177 }
171 BranchInstr* branch = new BranchInstr(value); 178 BranchInstr* branch = new BranchInstr(value);
172 AddInstruction(branch); 179 AddInstruction(branch);
173 CloseFragment(); 180 CloseFragment();
174 true_successor_address_ = branch->true_successor_address(); 181 true_successor_address_ = branch->true_successor_address();
175 false_successor_address_ = branch->false_successor_address(); 182 false_successor_address_ = branch->false_successor_address();
176 } 183 }
177 184
178 185
179 void EffectGraphVisitor::Bailout(const char* reason) { 186 void EffectGraphVisitor::Bailout(const char* reason) {
180 owner()->Bailout(reason); 187 owner()->Bailout(reason);
181 } 188 }
182 189
183 190
184 // <Statement> ::= Return { value: <Expression> 191 // <Statement> ::= Return { value: <Expression>
185 // inlined_finally_list: <InlinedFinally>* } 192 // inlined_finally_list: <InlinedFinally>* }
186 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { 193 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) {
187 ValueGraphVisitor for_value(owner(), temp_index()); 194 ValueGraphVisitor for_value(owner(), temp_index());
188 node->value()->Visit(&for_value); 195 node->value()->Visit(&for_value);
189 Append(for_value); 196 Append(for_value);
190 197
191 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { 198 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
192 EffectGraphVisitor for_effect(owner(), for_value.temp_index()); 199 EffectGraphVisitor for_effect(owner(), temp_index());
193 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); 200 node->InlinedFinallyNodeAt(i)->Visit(&for_effect);
194 Append(for_effect); 201 Append(for_effect);
195 if (!is_open()) return; 202 if (!is_open()) return;
196 } 203 }
197 204
198 Value* return_value = for_value.value(); 205 Value* return_value = for_value.value();
199 if (FLAG_enable_type_checks) { 206 if (FLAG_enable_type_checks) {
200 const RawFunction::Kind kind = owner()->parsed_function().function().kind(); 207 const RawFunction::Kind kind = owner()->parsed_function().function().kind();
201 const bool is_implicit_getter = 208 const bool is_implicit_getter =
202 (kind == RawFunction::kImplicitGetter) || 209 (kind == RawFunction::kImplicitGetter) ||
203 (kind == RawFunction::kConstImplicitGetter); 210 (kind == RawFunction::kConstImplicitGetter);
204 const bool is_static = owner()->parsed_function().function().is_static(); 211 const bool is_static = owner()->parsed_function().function().is_static();
205 // Implicit getters do not need a type check at return, unless they compute 212 // Implicit getters do not need a type check at return, unless they compute
206 // the initial value of a static field. 213 // the initial value of a static field.
207 if (is_static || !is_implicit_getter) { 214 if (is_static || !is_implicit_getter) {
208 const AbstractType& dst_type = 215 const AbstractType& dst_type =
209 AbstractType::ZoneHandle( 216 AbstractType::ZoneHandle(
210 owner()->parsed_function().function().result_type()); 217 owner()->parsed_function().function().result_type());
211 const String& dst_name = 218 const String& dst_name =
212 String::ZoneHandle(String::NewSymbol("function result")); 219 String::ZoneHandle(String::NewSymbol("function result"));
213 return_value = BuildAssignableValue(node->value(), 220 return_value = BuildAssignableValue(node->value(),
214 return_value, 221 return_value,
215 dst_type, 222 dst_type,
216 dst_name, 223 dst_name);
217 temp_index());
218 } 224 }
219 } 225 }
220 226
221 intptr_t current_context_level = owner()->context_level(); 227 intptr_t current_context_level = owner()->context_level();
222 ASSERT(current_context_level >= 0); 228 ASSERT(current_context_level >= 0);
223 if (owner()->parsed_function().saved_context_var() != NULL) { 229 if (owner()->parsed_function().saved_context_var() != NULL) {
224 // CTX on entry was saved, but not linked as context parent. 230 // CTX on entry was saved, but not linked as context parent.
225 BuildLoadContext(*owner()->parsed_function().saved_context_var()); 231 BuildLoadContext(*owner()->parsed_function().saved_context_var());
226 } else { 232 } else {
227 while (current_context_level-- > 0) { 233 while (current_context_level-- > 0) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 } 317 }
312 318
313 319
314 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { 320 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) {
315 ValueGraphVisitor for_value(owner(), temp_index()); 321 ValueGraphVisitor for_value(owner(), temp_index());
316 node->expr()->Visit(&for_value); 322 node->expr()->Visit(&for_value);
317 Append(for_value); 323 Append(for_value);
318 ReturnValue(BuildAssignableValue(node->expr(), 324 ReturnValue(BuildAssignableValue(node->expr(),
319 for_value.value(), 325 for_value.value(),
320 node->type(), 326 node->type(),
321 node->dst_name(), 327 node->dst_name()));
322 temp_index()));
323 } 328 }
324 329
325 330
326 // <Expression> :: BinaryOp { kind: Token::Kind 331 // <Expression> :: BinaryOp { kind: Token::Kind
327 // left: <Expression> 332 // left: <Expression>
328 // right: <Expression> } 333 // right: <Expression> }
329 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 334 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
330 // Operators "&&" and "||" cannot be overloaded therefore do not call 335 // Operators "&&" and "||" cannot be overloaded therefore do not call
331 // operator. 336 // operator.
332 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 337 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
333 // See ValueGraphVisitor::VisitBinaryOpNode. 338 // See ValueGraphVisitor::VisitBinaryOpNode.
334 TestGraphVisitor for_left(owner(), 339 TestGraphVisitor for_left(owner(),
335 temp_index(), 340 temp_index(),
336 node->left()->token_index()); 341 node->left()->token_index());
337 node->left()->Visit(&for_left); 342 node->left()->Visit(&for_left);
338 EffectGraphVisitor for_right(owner(), temp_index()); 343 EffectGraphVisitor for_right(owner(), temp_index());
339 node->right()->Visit(&for_right); 344 node->right()->Visit(&for_right);
340 EffectGraphVisitor empty(owner(), temp_index()); 345 EffectGraphVisitor empty(owner(), temp_index());
341 if (node->kind() == Token::kAND) { 346 if (node->kind() == Token::kAND) {
342 Join(for_left, for_right, empty); 347 Join(for_left, for_right, empty);
343 } else { 348 } else {
344 Join(for_left, empty, for_right); 349 Join(for_left, empty, for_right);
345 } 350 }
346 return; 351 return;
347 } 352 }
348 ValueGraphVisitor for_left_value(owner(), temp_index()); 353 ValueGraphVisitor for_left_value(owner(), temp_index());
349 node->left()->Visit(&for_left_value); 354 node->left()->Visit(&for_left_value);
350 Append(for_left_value); 355 Append(for_left_value);
351 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); 356 ValueGraphVisitor for_right_value(owner(), temp_index());
352 node->right()->Visit(&for_right_value); 357 node->right()->Visit(&for_right_value);
353 Append(for_right_value); 358 Append(for_right_value);
354 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); 359 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
355 arguments->Add(for_left_value.value()); 360 arguments->Add(for_left_value.value());
356 arguments->Add(for_right_value.value()); 361 arguments->Add(for_right_value.value());
357 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); 362 const String& name = String::ZoneHandle(String::NewSymbol(node->Name()));
358 InstanceCallComp* call = new InstanceCallComp(node->token_index(), 363 InstanceCallComp* call = new InstanceCallComp(node->token_index(),
359 owner()->try_index(), 364 owner()->try_index(),
360 name, 365 name,
361 arguments, 366 arguments,
(...skipping 18 matching lines...) Expand all
380 TestGraphVisitor for_test(owner(), 385 TestGraphVisitor for_test(owner(),
381 temp_index(), 386 temp_index(),
382 node->left()->token_index()); 387 node->left()->token_index());
383 node->left()->Visit(&for_test); 388 node->left()->Visit(&for_test);
384 389
385 ValueGraphVisitor for_right(owner(), temp_index()); 390 ValueGraphVisitor for_right(owner(), temp_index());
386 node->right()->Visit(&for_right); 391 node->right()->Visit(&for_right);
387 Value* right_value = for_right.value(); 392 Value* right_value = for_right.value();
388 if (FLAG_enable_type_checks) { 393 if (FLAG_enable_type_checks) {
389 BindInstr* assert_boolean = 394 BindInstr* assert_boolean =
390 new BindInstr(temp_index(), 395 new BindInstr(new AssertBooleanComp(node->right()->token_index(),
391 new AssertBooleanComp(node->right()->token_index(),
392 owner()->try_index(), 396 owner()->try_index(),
393 right_value)); 397 right_value));
394 for_right.AddInstruction(assert_boolean); 398 for_right.AddInstruction(assert_boolean);
395 right_value = new UseVal(assert_boolean); 399 right_value = new UseVal(assert_boolean);
396 } 400 }
397 BindInstr* constant_true = 401 BindInstr* constant_true = new BindInstr(new ConstantVal(bool_true));
398 new BindInstr(temp_index(), new ConstantVal(bool_true));
399 for_right.AddInstruction(constant_true); 402 for_right.AddInstruction(constant_true);
400 StrictCompareComp* comp = new StrictCompareComp(Token::kEQ_STRICT, 403 StrictCompareComp* comp = new StrictCompareComp(Token::kEQ_STRICT,
401 right_value, new UseVal(constant_true)); 404 right_value, new UseVal(constant_true));
402 for_right.AddInstruction(new BindInstr(temp_index(), comp)); 405 for_right.AddInstruction(new BindInstr(comp));
403 406
404 if (node->kind() == Token::kAND) { 407 if (node->kind() == Token::kAND) {
405 ValueGraphVisitor for_false(owner(), temp_index()); 408 ValueGraphVisitor for_false(owner(), temp_index());
406 for_false.ReturnComputation(new ConstantVal(bool_false)); 409 for_false.ReturnComputation(new ConstantVal(bool_false));
407 Join(for_test, for_right, for_false); 410 Join(for_test, for_right, for_false);
408 } else { 411 } else {
409 ASSERT(node->kind() == Token::kOR); 412 ASSERT(node->kind() == Token::kOR);
410 ValueGraphVisitor for_true(owner(), temp_index()); 413 ValueGraphVisitor for_true(owner(), temp_index());
411 for_true.ReturnComputation(new ConstantVal(bool_true)); 414 for_true.ReturnComputation(new ConstantVal(bool_true));
412 Join(for_test, for_true, for_right); 415 Join(for_test, for_true, for_right);
413 } 416 }
414 ReturnValue(new TempVal(AllocateTempIndex())); 417 ReturnValue(new TempVal(temp_index() - 1));
415 return; 418 return;
416 } 419 }
417 EffectGraphVisitor::VisitBinaryOpNode(node); 420 EffectGraphVisitor::VisitBinaryOpNode(node);
418 } 421 }
419 422
420 423
421 void EffectGraphVisitor::CompiletimeStringInterpolation( 424 void EffectGraphVisitor::CompiletimeStringInterpolation(
422 const Function& interpol_func, const Array& literals) { 425 const Function& interpol_func, const Array& literals) {
423 // Do nothing. 426 // Do nothing.
424 } 427 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 } 480 }
478 if (compile_time_interpolation) { 481 if (compile_time_interpolation) {
479 // Not needed for effect, only for value 482 // Not needed for effect, only for value
480 CompiletimeStringInterpolation(interpol_func, literals); 483 CompiletimeStringInterpolation(interpol_func, literals);
481 return; 484 return;
482 } 485 }
483 // Runtime string interpolation. 486 // Runtime string interpolation.
484 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(); 487 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>();
485 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index()); 488 ArgumentListNode* interpol_arg = new ArgumentListNode(node->token_index());
486 interpol_arg->Add(node->values()); 489 interpol_arg->Add(node->values());
487 TranslateArgumentList(*interpol_arg, temp_index(), values); 490 TranslateArgumentList(*interpol_arg, values);
488 StaticCallComp* call = 491 StaticCallComp* call =
489 new StaticCallComp(node->token_index(), 492 new StaticCallComp(node->token_index(),
490 owner()->try_index(), 493 owner()->try_index(),
491 interpol_func, 494 interpol_func,
492 interpol_arg->names(), 495 interpol_arg->names(),
493 values); 496 values);
494 ReturnComputation(call); 497 ReturnComputation(call);
495 } 498 }
496 499
497 500
498 void EffectGraphVisitor::BuildAssertAssignable(intptr_t token_index, 501 void EffectGraphVisitor::BuildAssertAssignable(intptr_t token_index,
499 Value* value, 502 Value* value,
500 const AbstractType& dst_type, 503 const AbstractType& dst_type,
501 const String& dst_name, 504 const String& dst_name) {
502 intptr_t start_index) {
503 // Build the type check computation. 505 // Build the type check computation.
504 Value* instantiator_type_arguments = NULL; 506 Value* instantiator_type_arguments = NULL;
505 if (!dst_type.IsInstantiated()) { 507 if (!dst_type.IsInstantiated()) {
506 instantiator_type_arguments = 508 instantiator_type_arguments =
507 BuildInstantiatorTypeArguments(token_index, start_index + 1); 509 BuildInstantiatorTypeArguments(token_index);
508 } 510 }
509 AssertAssignableComp* assert_assignable = 511 AssertAssignableComp* assert_assignable =
510 new AssertAssignableComp(token_index, 512 new AssertAssignableComp(token_index,
511 owner()->try_index(), 513 owner()->try_index(),
512 value, 514 value,
513 instantiator_type_arguments, 515 instantiator_type_arguments,
514 dst_type, 516 dst_type,
515 dst_name); 517 dst_name);
516 AddInstruction(new DoInstr(assert_assignable)); 518 AddInstruction(new DoInstr(assert_assignable));
517 } 519 }
518 520
519 521
520 Value* EffectGraphVisitor::BuildAssignableValue(AstNode* value_node, 522 Value* EffectGraphVisitor::BuildAssignableValue(AstNode* value_node,
521 Value* value, 523 Value* value,
522 const AbstractType& dst_type, 524 const AbstractType& dst_type,
523 const String& dst_name, 525 const String& dst_name) {
524 intptr_t start_index) {
525 if (CanSkipTypeCheck(value_node, dst_type)) { 526 if (CanSkipTypeCheck(value_node, dst_type)) {
526 return value; 527 return value;
527 } 528 }
528 529
529 // Build the type check computation. 530 // Build the type check computation.
530 Value* instantiator_type_arguments = NULL; 531 Value* instantiator_type_arguments = NULL;
531 if (!dst_type.IsInstantiated()) { 532 if (!dst_type.IsInstantiated()) {
532 instantiator_type_arguments = 533 instantiator_type_arguments =
533 BuildInstantiatorTypeArguments(value_node->token_index(), 534 BuildInstantiatorTypeArguments(value_node->token_index());
534 start_index + 1);
535 } 535 }
536 BindInstr* assert_assignable = 536 BindInstr* assert_assignable =
537 new BindInstr(start_index, 537 new BindInstr(new AssertAssignableComp(value_node->token_index(),
538 new AssertAssignableComp(value_node->token_index(),
539 owner()->try_index(), 538 owner()->try_index(),
540 value, 539 value,
541 instantiator_type_arguments, 540 instantiator_type_arguments,
542 dst_type, 541 dst_type,
543 dst_name)); 542 dst_name));
544 AddInstruction(assert_assignable); 543 AddInstruction(assert_assignable);
545 return new UseVal(assert_assignable); 544 return new UseVal(assert_assignable);
546 } 545 }
547 546
548 547
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 ReturnComputation(result); 601 ReturnComputation(result);
603 return; 602 return;
604 } 603 }
605 604
606 ValueGraphVisitor for_left_value(owner(), temp_index()); 605 ValueGraphVisitor for_left_value(owner(), temp_index());
607 node->left()->Visit(&for_left_value); 606 node->left()->Visit(&for_left_value);
608 Append(for_left_value); 607 Append(for_left_value);
609 Value* type_arguments = NULL; 608 Value* type_arguments = NULL;
610 if (!type.IsInstantiated()) { 609 if (!type.IsInstantiated()) {
611 type_arguments = 610 type_arguments =
612 BuildInstantiatorTypeArguments(node->token_index(), 611 BuildInstantiatorTypeArguments(node->token_index());
613 for_left_value.temp_index());
614 } 612 }
615 InstanceOfComp* instance_of = 613 InstanceOfComp* instance_of =
616 new InstanceOfComp(node->token_index(), 614 new InstanceOfComp(node->token_index(),
617 owner()->try_index(), 615 owner()->try_index(),
618 for_left_value.value(), 616 for_left_value.value(),
619 type_arguments, 617 type_arguments,
620 node->right()->AsTypeNode()->type(), 618 node->right()->AsTypeNode()->type(),
621 (node->kind() == Token::kISNOT)); 619 (node->kind() == Token::kISNOT));
622 ReturnComputation(instance_of); 620 ReturnComputation(instance_of);
623 } 621 }
624 622
625 623
626 // <Expression> :: Comparison { kind: Token::Kind 624 // <Expression> :: Comparison { kind: Token::Kind
627 // left: <Expression> 625 // left: <Expression>
628 // right: <Expression> } 626 // right: <Expression> }
629 // TODO(srdjan): Implement new equality. 627 // TODO(srdjan): Implement new equality.
630 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { 628 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
631 if (Token::IsInstanceofOperator(node->kind())) { 629 if (Token::IsInstanceofOperator(node->kind())) {
632 BuildInstanceOf(node); 630 BuildInstanceOf(node);
633 return; 631 return;
634 } 632 }
635 if ((node->kind() == Token::kEQ_STRICT) || 633 if ((node->kind() == Token::kEQ_STRICT) ||
636 (node->kind() == Token::kNE_STRICT)) { 634 (node->kind() == Token::kNE_STRICT)) {
637 ValueGraphVisitor for_left_value(owner(), temp_index()); 635 ValueGraphVisitor for_left_value(owner(), temp_index());
638 node->left()->Visit(&for_left_value); 636 node->left()->Visit(&for_left_value);
639 Append(for_left_value); 637 Append(for_left_value);
640 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); 638 ValueGraphVisitor for_right_value(owner(), temp_index());
641 node->right()->Visit(&for_right_value); 639 node->right()->Visit(&for_right_value);
642 Append(for_right_value); 640 Append(for_right_value);
643 StrictCompareComp* comp = new StrictCompareComp( 641 StrictCompareComp* comp = new StrictCompareComp(
644 node->kind(), for_left_value.value(), for_right_value.value()); 642 node->kind(), for_left_value.value(), for_right_value.value());
645 ReturnComputation(comp); 643 ReturnComputation(comp);
646 return; 644 return;
647 } 645 }
648 646
649 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { 647 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) {
650 ValueGraphVisitor for_left_value(owner(), temp_index()); 648 ValueGraphVisitor for_left_value(owner(), temp_index());
651 node->left()->Visit(&for_left_value); 649 node->left()->Visit(&for_left_value);
652 Append(for_left_value); 650 Append(for_left_value);
653 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); 651 ValueGraphVisitor for_right_value(owner(), temp_index());
654 node->right()->Visit(&for_right_value); 652 node->right()->Visit(&for_right_value);
655 Append(for_right_value); 653 Append(for_right_value);
656 EqualityCompareComp* comp = new EqualityCompareComp( 654 EqualityCompareComp* comp = new EqualityCompareComp(
657 node->token_index(), owner()->try_index(), 655 node->token_index(), owner()->try_index(),
658 for_left_value.value(), for_right_value.value()); 656 for_left_value.value(), for_right_value.value());
659 if (node->kind() == Token::kEQ) { 657 if (node->kind() == Token::kEQ) {
660 ReturnComputation(comp); 658 ReturnComputation(comp);
661 } else { 659 } else {
662 Definition* eq_result = new BindInstr(temp_index(), comp); 660 Definition* eq_result = new BindInstr(comp);
663 AddInstruction(eq_result); 661 AddInstruction(eq_result);
664 if (FLAG_enable_type_checks) { 662 if (FLAG_enable_type_checks) {
665 eq_result = 663 eq_result =
666 new BindInstr(temp_index(), 664 new BindInstr(new AssertBooleanComp(node->token_index(),
667 new AssertBooleanComp(node->token_index(),
668 owner()->try_index(), 665 owner()->try_index(),
669 new UseVal(eq_result))); 666 new UseVal(eq_result)));
670 AddInstruction(eq_result); 667 AddInstruction(eq_result);
671 } 668 }
672 BooleanNegateComp* negate = new BooleanNegateComp(new UseVal(eq_result)); 669 BooleanNegateComp* negate = new BooleanNegateComp(new UseVal(eq_result));
673 ReturnComputation(negate); 670 ReturnComputation(negate);
674 } 671 }
675 return; 672 return;
676 } 673 }
677 674
678 ValueGraphVisitor for_left_value(owner(), temp_index()); 675 ValueGraphVisitor for_left_value(owner(), temp_index());
679 node->left()->Visit(&for_left_value); 676 node->left()->Visit(&for_left_value);
680 Append(for_left_value); 677 Append(for_left_value);
681 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index()); 678 ValueGraphVisitor for_right_value(owner(), temp_index());
682 node->right()->Visit(&for_right_value); 679 node->right()->Visit(&for_right_value);
683 Append(for_right_value); 680 Append(for_right_value);
684 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); 681 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
685 arguments->Add(for_left_value.value()); 682 arguments->Add(for_left_value.value());
686 arguments->Add(for_right_value.value()); 683 arguments->Add(for_right_value.value());
687 const String& name = String::ZoneHandle(String::NewSymbol(node->Name())); 684 const String& name = String::ZoneHandle(String::NewSymbol(node->Name()));
688 InstanceCallComp* call = new InstanceCallComp( 685 InstanceCallComp* call = new InstanceCallComp(
689 node->token_index(), owner()->try_index(), name, 686 node->token_index(), owner()->try_index(), name,
690 arguments, Array::ZoneHandle(), 2); 687 arguments, Array::ZoneHandle(), 2);
691 ReturnComputation(call); 688 ReturnComputation(call);
692 } 689 }
693 690
694 691
695 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { 692 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
696 // "!" cannot be overloaded, therefore do not call operator. 693 // "!" cannot be overloaded, therefore do not call operator.
697 if (node->kind() == Token::kNOT) { 694 if (node->kind() == Token::kNOT) {
698 ValueGraphVisitor for_value(owner(), temp_index()); 695 ValueGraphVisitor for_value(owner(), temp_index());
699 node->operand()->Visit(&for_value); 696 node->operand()->Visit(&for_value);
700 Append(for_value); 697 Append(for_value);
701 Value* value = for_value.value(); 698 Value* value = for_value.value();
702 if (FLAG_enable_type_checks) { 699 if (FLAG_enable_type_checks) {
703 BindInstr* assert_boolean = 700 BindInstr* assert_boolean =
704 new BindInstr(temp_index(), 701 new BindInstr(new AssertBooleanComp(node->operand()->token_index(),
705 new AssertBooleanComp(node->operand()->token_index(),
706 owner()->try_index(), 702 owner()->try_index(),
707 value)); 703 value));
708 AddInstruction(assert_boolean); 704 AddInstruction(assert_boolean);
709 value = new UseVal(assert_boolean); 705 value = new UseVal(assert_boolean);
710 } 706 }
711 BooleanNegateComp* negate = new BooleanNegateComp(value); 707 BooleanNegateComp* negate = new BooleanNegateComp(value);
712 ReturnComputation(negate); 708 ReturnComputation(negate);
713 return; 709 return;
714 } 710 }
715 ValueGraphVisitor for_value(owner(), temp_index()); 711 ValueGraphVisitor for_value(owner(), temp_index());
(...skipping 12 matching lines...) Expand all
728 } 724 }
729 725
730 726
731 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { 727 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) {
732 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); 728 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR));
733 // In an effect context, treat postincrement as if it were preincrement 729 // In an effect context, treat postincrement as if it were preincrement
734 // because its value is not needed. 730 // because its value is not needed.
735 731
736 // 1. Load the value. 732 // 1. Load the value.
737 BindInstr* load = 733 BindInstr* load =
738 new BindInstr(temp_index(), 734 new BindInstr(new LoadLocalComp(node->local(), owner()->context_level()));
739 new LoadLocalComp(node->local(), owner()->context_level()));
740 AddInstruction(load); 735 AddInstruction(load);
741 AllocateTempIndex();
742 // 2. Increment. 736 // 2. Increment.
743 Definition* incr = 737 Definition* incr =
744 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); 738 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load));
745 // 3. Perform the store, resulting in the new value. 739 // 3. Perform the store, resulting in the new value.
746 DeallocateTempIndex(); // Consuming incr.
747 StoreLocalComp* store = new StoreLocalComp( 740 StoreLocalComp* store = new StoreLocalComp(
748 node->local(), new UseVal(incr), owner()->context_level()); 741 node->local(), new UseVal(incr), owner()->context_level());
749 ReturnComputation(store); 742 ReturnComputation(store);
750 } 743 }
751 744
752 745
753 void ValueGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) { 746 void ValueGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) {
754 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); 747 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR));
755 if (node->prefix()) { 748 if (node->prefix()) {
756 // Base class handles preincrement. 749 // Base class handles preincrement.
757 EffectGraphVisitor::VisitIncrOpLocalNode(node); 750 EffectGraphVisitor::VisitIncrOpLocalNode(node);
758 return; 751 return;
759 } 752 }
760 // For postincrement, duplicate the original value to use one copy as the 753 // For postincrement, duplicate the original value to use one copy as the
761 // result. 754 // result.
762 // 755 //
763 // 1. Load the value. 756 // 1. Load the value.
764 BindInstr* load = 757 BindInstr* load =
765 new BindInstr(temp_index(), 758 new BindInstr(new LoadLocalComp(node->local(), owner()->context_level()));
766 new LoadLocalComp(node->local(), owner()->context_level()));
767 AddInstruction(load); 759 AddInstruction(load);
768 AllocateTempIndex();
769 // 2. Duplicate it to increment. 760 // 2. Duplicate it to increment.
770 PickTempInstr* duplicate = 761 PickTempInstr* duplicate = new PickTempInstr(load->temp_index());
771 new PickTempInstr(temp_index(), load->temp_index());
772 AddInstruction(duplicate); 762 AddInstruction(duplicate);
773 AllocateTempIndex();
774 // 3. Increment. 763 // 3. Increment.
775 Definition* incr = 764 Definition* incr =
776 BuildIncrOpIncrement(node->kind(), node->token_index(), 765 BuildIncrOpIncrement(node->kind(), node->token_index(),
777 new UseVal(duplicate)); 766 new UseVal(duplicate));
778 // 4. Perform the store and return the original value. 767 // 4. Perform the store and return the original value.
779 DeallocateTempIndex(); // Consuming incr.
780 StoreLocalComp* store = new StoreLocalComp( 768 StoreLocalComp* store = new StoreLocalComp(
781 node->local(), new UseVal(incr), owner()->context_level()); 769 node->local(), new UseVal(incr), owner()->context_level());
782 AddInstruction(new DoInstr(store)); 770 AddInstruction(new DoInstr(store));
783 ReturnValue(new UseVal(load)); 771 ReturnValue(new UseVal(load));
784 } 772 }
785 773
786 774
787 Definition* EffectGraphVisitor::BuildIncrOpFieldLoad( 775 Definition* EffectGraphVisitor::BuildIncrOpFieldLoad(
788 IncrOpInstanceFieldNode* node, 776 IncrOpInstanceFieldNode* node,
789 Value** receiver) { 777 Value** receiver) {
790 // Evaluate the receiver and duplicate it (it has two uses). 778 // Evaluate the receiver and duplicate it (it has two uses).
791 // t_n <- ... receiver ... 779 // t_n <- ... receiver ...
792 // t_n+1 <- Pick(t_n) 780 // t_n+1 <- Pick(t_n)
793 ValueGraphVisitor for_receiver(owner(), temp_index()); 781 ValueGraphVisitor for_receiver(owner(), temp_index());
794 node->receiver()->Visit(&for_receiver); 782 node->receiver()->Visit(&for_receiver);
795 Append(for_receiver); 783 Append(for_receiver);
796 AllocateTempIndex();
797 ASSERT(temp_index() == for_receiver.temp_index()); 784 ASSERT(temp_index() == for_receiver.temp_index());
798 PickTempInstr* duplicate = 785 PickTempInstr* duplicate = new PickTempInstr(temp_index() - 1);
799 new PickTempInstr(temp_index(), temp_index() - 1);
800 AddInstruction(duplicate); 786 AddInstruction(duplicate);
801 787
802 // Load the value. 788 // Load the value.
803 // t_n+1 <- InstanceCall(get:name, t_n+1) 789 // t_n+1 <- InstanceCall(get:name, t_n+1)
804 const String& getter_name = 790 const String& getter_name =
805 String::ZoneHandle(Field::GetterSymbol(node->field_name())); 791 String::ZoneHandle(Field::GetterSymbol(node->field_name()));
806 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); 792 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1);
807 arguments->Add(new UseVal(duplicate)); 793 arguments->Add(new UseVal(duplicate));
808 BindInstr* load = 794 BindInstr* load =
809 new BindInstr(temp_index(), 795 new BindInstr(new InstanceCallComp(
810 new InstanceCallComp(
811 node->token_index(), 796 node->token_index(),
812 owner()->try_index(), getter_name, arguments, 797 owner()->try_index(), getter_name, arguments,
813 Array::ZoneHandle(), 1)); 798 Array::ZoneHandle(), 1));
814 AddInstruction(load); 799 AddInstruction(load);
815 AllocateTempIndex();
816 800
817 *receiver = for_receiver.value(); 801 *receiver = for_receiver.value();
818 return load; 802 return load;
819 } 803 }
820 804
821 805
822 Definition* EffectGraphVisitor::BuildIncrOpIncrement(Token::Kind kind, 806 Definition* EffectGraphVisitor::BuildIncrOpIncrement(Token::Kind kind,
823 intptr_t token_index, 807 intptr_t token_index,
824 Value* original) { 808 Value* original) {
825 ASSERT((kind == Token::kINCR) || (kind == Token::kDECR)); 809 ASSERT((kind == Token::kINCR) || (kind == Token::kDECR));
826 // Assumed that t_n-1 (where n is start_index) is the field value. 810 // Assumed that t_n-1 (where n is start_index) is the field value.
827 // t_n <- #1 811 // t_n <- #1
828 // t_n-1 <- InstanceCall(op, t_n-1, t_n) 812 // t_n-1 <- InstanceCall(op, t_n-1, t_n)
829 BindInstr* one = 813 BindInstr* one =
830 new BindInstr(temp_index(), 814 new BindInstr(new ConstantVal(Smi::ZoneHandle(Smi::New(1))));
831 new ConstantVal(Smi::ZoneHandle(Smi::New(1))));
832 AddInstruction(one); 815 AddInstruction(one);
833 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); 816 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
834 arguments->Add(original); 817 arguments->Add(original);
835 arguments->Add(new UseVal(one)); 818 arguments->Add(new UseVal(one));
836 const String& op_name = 819 const String& op_name =
837 String::ZoneHandle(String::NewSymbol((kind == Token::kINCR) ? "+" : "-")); 820 String::ZoneHandle(String::NewSymbol((kind == Token::kINCR) ? "+" : "-"));
838 DeallocateTempIndex(); // Consuming original.
839 BindInstr* add = 821 BindInstr* add =
840 new BindInstr(temp_index(), 822 new BindInstr(new InstanceCallComp(
841 new InstanceCallComp(
842 token_index, owner()->try_index(), op_name, 823 token_index, owner()->try_index(), op_name,
843 arguments, Array::ZoneHandle(), 2)); 824 arguments, Array::ZoneHandle(), 2));
844 AddInstruction(add); 825 AddInstruction(add);
845 AllocateTempIndex();
846 return add; 826 return add;
847 } 827 }
848 828
849 829
850 void EffectGraphVisitor::VisitIncrOpInstanceFieldNode( 830 void EffectGraphVisitor::VisitIncrOpInstanceFieldNode(
851 IncrOpInstanceFieldNode* node) { 831 IncrOpInstanceFieldNode* node) {
852 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); 832 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR));
853 // In an effect context, treat postincrement as if it were preincrement 833 // In an effect context, treat postincrement as if it were preincrement
854 // because its value is not needed. 834 // because its value is not needed.
855 835
856 // 1. Load the value. 836 // 1. Load the value.
857 Value* receiver = NULL; 837 Value* receiver = NULL;
858 Definition* load = BuildIncrOpFieldLoad(node, &receiver); 838 Definition* load = BuildIncrOpFieldLoad(node, &receiver);
859 // 2. Increment. 839 // 2. Increment.
860 Definition* incr = 840 Definition* incr =
861 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); 841 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load));
862 // 3. Perform the store, returning the stored value. 842 // 3. Perform the store, returning the stored value.
863 InstanceSetterComp* store = 843 InstanceSetterComp* store =
864 new InstanceSetterComp(node->token_index(), 844 new InstanceSetterComp(node->token_index(),
865 owner()->try_index(), 845 owner()->try_index(),
866 node->field_name(), 846 node->field_name(),
867 receiver, 847 receiver,
868 new UseVal(incr)); 848 new UseVal(incr));
869 DeallocateTempIndex(); // Consuming incr.
870 DeallocateTempIndex(); // Consuming receiver.
871 ReturnComputation(store); 849 ReturnComputation(store);
872 } 850 }
873 851
874 852
875 void ValueGraphVisitor::VisitIncrOpInstanceFieldNode( 853 void ValueGraphVisitor::VisitIncrOpInstanceFieldNode(
876 IncrOpInstanceFieldNode* node) { 854 IncrOpInstanceFieldNode* node) {
877 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); 855 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR));
878 if (node->prefix()) { 856 if (node->prefix()) {
879 // Base class handles preincrement. 857 // Base class handles preincrement.
880 EffectGraphVisitor::VisitIncrOpInstanceFieldNode(node); 858 EffectGraphVisitor::VisitIncrOpInstanceFieldNode(node);
881 return; 859 return;
882 } 860 }
883 // For postincrement, preallocate a temporary to preserve the original 861 // For postincrement, preallocate a temporary to preserve the original
884 // value. 862 // value.
885 // 863 //
886 // 1. Name a placeholder. 864 // 1. Name a placeholder.
887 BindInstr* placeholder = 865 BindInstr* placeholder =
888 new BindInstr(temp_index(), 866 new BindInstr(new ConstantVal(Smi::ZoneHandle(Smi::New(0))));
889 new ConstantVal(Smi::ZoneHandle(Smi::New(0))));
890 AddInstruction(placeholder); 867 AddInstruction(placeholder);
891 AllocateTempIndex();
892 // 2. Load the value. 868 // 2. Load the value.
893 Value* receiver = NULL; 869 Value* receiver = NULL;
894 Definition* load = BuildIncrOpFieldLoad(node, &receiver); 870 Definition* load = BuildIncrOpFieldLoad(node, &receiver);
895 // 3. Preserve the original value. 871 // 3. Preserve the original value.
896 AddInstruction(new TuckTempInstr(placeholder->temp_index(), 872 AddInstruction(new TuckTempInstr(placeholder->temp_index(),
897 load->temp_index())); 873 load->temp_index()));
898 // 4. Increment. 874 // 4. Increment.
899 Definition* incr = 875 Definition* incr =
900 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); 876 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load));
901 // 5. Perform the store and return the original value. 877 // 5. Perform the store and return the original value.
902 const String& setter_name = 878 const String& setter_name =
903 String::ZoneHandle(Field::SetterSymbol(node->field_name())); 879 String::ZoneHandle(Field::SetterSymbol(node->field_name()));
904 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); 880 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
905 arguments->Add(receiver); 881 arguments->Add(receiver);
906 arguments->Add(new UseVal(incr)); 882 arguments->Add(new UseVal(incr));
907 InstanceCallComp* store = new InstanceCallComp( 883 InstanceCallComp* store = new InstanceCallComp(
908 node->token_index(), owner()->try_index(), 884 node->token_index(), owner()->try_index(),
909 setter_name, arguments, Array::ZoneHandle(), 1); 885 setter_name, arguments, Array::ZoneHandle(), 1);
910 DeallocateTempIndex(); // Consuming incr.
911 DeallocateTempIndex(); // Consuming receiver.
912 AddInstruction(new DoInstr(store)); 886 AddInstruction(new DoInstr(store));
913 ReturnValue(new UseVal(placeholder)); 887 ReturnValue(new UseVal(placeholder));
914 } 888 }
915 889
916 890
917 Definition* EffectGraphVisitor::BuildIncrOpIndexedLoad( 891 Definition* EffectGraphVisitor::BuildIncrOpIndexedLoad(
918 IncrOpIndexedNode* node, 892 IncrOpIndexedNode* node,
919 Value** receiver, 893 Value** receiver,
920 Value** index) { 894 Value** index) {
921 // Evaluate the receiver and index. 895 // Evaluate the receiver and index.
922 // t_n <- ... receiver ... 896 // t_n <- ... receiver ...
923 // t_n+1 <- ... index ... 897 // t_n+1 <- ... index ...
924 ValueGraphVisitor for_receiver(owner(), temp_index()); 898 ValueGraphVisitor for_receiver(owner(), temp_index());
925 node->array()->Visit(&for_receiver); 899 node->array()->Visit(&for_receiver);
926 Append(for_receiver); 900 Append(for_receiver);
927 AllocateTempIndex();
928 ASSERT(temp_index() == for_receiver.temp_index()); 901 ASSERT(temp_index() == for_receiver.temp_index());
929 902
930 ValueGraphVisitor for_index(owner(), temp_index()); 903 ValueGraphVisitor for_index(owner(), temp_index());
931 node->index()->Visit(&for_index); 904 node->index()->Visit(&for_index);
932 Append(for_index); 905 Append(for_index);
933 AllocateTempIndex();
934 ASSERT(temp_index() == for_index.temp_index()); 906 ASSERT(temp_index() == for_index.temp_index());
935 907
936 // Duplicate the receiver and index values, load the value. 908 // Duplicate the receiver and index values, load the value.
937 // t_n+2 <- Pick(t_n) 909 // t_n+2 <- Pick(t_n)
938 // t_n+3 <- Pick(t_n+1) 910 // t_n+3 <- Pick(t_n+1)
939 // t_n+2 <- InstanceCall([], t_n+2, t_n+3) 911 // t_n+2 <- InstanceCall([], t_n+2, t_n+3)
940 PickTempInstr* duplicate_receiver = 912 PickTempInstr* duplicate_receiver = new PickTempInstr(temp_index() - 2);
941 new PickTempInstr(temp_index(), temp_index() - 2);
942 AddInstruction(duplicate_receiver); 913 AddInstruction(duplicate_receiver);
943 PickTempInstr* duplicate_index = 914 PickTempInstr* duplicate_index = new PickTempInstr(temp_index() - 2);
944 new PickTempInstr(temp_index() + 1, temp_index() - 1);
945 AddInstruction(duplicate_index); 915 AddInstruction(duplicate_index);
946 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2); 916 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
947 arguments->Add(new UseVal(duplicate_receiver)); 917 arguments->Add(new UseVal(duplicate_receiver));
948 arguments->Add(new UseVal(duplicate_index)); 918 arguments->Add(new UseVal(duplicate_index));
949 const String& load_name = 919 const String& load_name =
950 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX))); 920 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kINDEX)));
951 BindInstr* load = 921 BindInstr* load =
952 new BindInstr(temp_index(), 922 new BindInstr(new InstanceCallComp(
953 new InstanceCallComp(
954 node->token_index(), 923 node->token_index(),
955 owner()->try_index(), load_name, arguments, 924 owner()->try_index(), load_name, arguments,
956 Array::ZoneHandle(), 1)); 925 Array::ZoneHandle(), 1));
957 AddInstruction(load); 926 AddInstruction(load);
958 AllocateTempIndex();
959 927
960 *receiver = for_receiver.value(); 928 *receiver = for_receiver.value();
961 *index = for_index.value(); 929 *index = for_index.value();
962 return load; 930 return load;
963 } 931 }
964 932
965 933
966 void EffectGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { 934 void EffectGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) {
967 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); 935 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR));
968 // In an effect context, treat postincrement as if it were preincrement 936 // In an effect context, treat postincrement as if it were preincrement
969 // because its value is not needed. 937 // because its value is not needed.
970 938
971 // 1. Load the value. 939 // 1. Load the value.
972 Value* receiver = NULL; 940 Value* receiver = NULL;
973 Value* index = NULL; 941 Value* index = NULL;
974 Definition* load = BuildIncrOpIndexedLoad(node, &receiver, &index); 942 Definition* load = BuildIncrOpIndexedLoad(node, &receiver, &index);
975 // 2. Increment. 943 // 2. Increment.
976 Definition* incr = 944 Definition* incr =
977 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); 945 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load));
978 // 3. Perform the store, returning the stored value. 946 // 3. Perform the store, returning the stored value.
979 StoreIndexedComp* store = new StoreIndexedComp(node->token_index(), 947 StoreIndexedComp* store = new StoreIndexedComp(node->token_index(),
980 owner()->try_index(), 948 owner()->try_index(),
981 receiver, 949 receiver,
982 index, 950 index,
983 new UseVal(incr)); 951 new UseVal(incr));
984 DeallocateTempIndex(); // Consuming incr.
985 DeallocateTempIndex(); // Consuming index.
986 DeallocateTempIndex(); // Consuming receiver.
987 ReturnComputation(store); 952 ReturnComputation(store);
988 } 953 }
989 954
990 955
991 void ValueGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) { 956 void ValueGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) {
992 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR)); 957 ASSERT((node->kind() == Token::kINCR) || (node->kind() == Token::kDECR));
993 if (node->prefix()) { 958 if (node->prefix()) {
994 // Base class handles preincrement. 959 // Base class handles preincrement.
995 EffectGraphVisitor::VisitIncrOpIndexedNode(node); 960 EffectGraphVisitor::VisitIncrOpIndexedNode(node);
996 return; 961 return;
997 } 962 }
998 // For postincrement, preallocate a temporary to preserve the original 963 // For postincrement, preallocate a temporary to preserve the original
999 // value. 964 // value.
1000 // 965 //
1001 // 1. Name a placeholder. 966 // 1. Name a placeholder.
1002 BindInstr* placeholder = 967 BindInstr* placeholder =
1003 new BindInstr(temp_index(), 968 new BindInstr(new ConstantVal(Smi::ZoneHandle(Smi::New(0))));
1004 new ConstantVal(Smi::ZoneHandle(Smi::New(0))));
1005 AddInstruction(placeholder); 969 AddInstruction(placeholder);
1006 AllocateTempIndex();
1007 // 2. Load the value. 970 // 2. Load the value.
1008 Value* receiver = NULL; 971 Value* receiver = NULL;
1009 Value* index = NULL; 972 Value* index = NULL;
1010 Definition* load = BuildIncrOpIndexedLoad(node, &receiver, &index); 973 Definition* load = BuildIncrOpIndexedLoad(node, &receiver, &index);
1011 // 3. Preserve the original value. 974 // 3. Preserve the original value.
1012 AddInstruction(new TuckTempInstr(placeholder->temp_index(), 975 AddInstruction(new TuckTempInstr(placeholder->temp_index(),
1013 load->temp_index())); 976 load->temp_index()));
1014 // 4. Increment. 977 // 4. Increment.
1015 Definition* incr = 978 Definition* incr =
1016 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load)); 979 BuildIncrOpIncrement(node->kind(), node->token_index(), new UseVal(load));
1017 // 5. Perform the store and return the original value. 980 // 5. Perform the store and return the original value.
1018 const String& store_name = 981 const String& store_name =
1019 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX))); 982 String::ZoneHandle(String::NewSymbol(Token::Str(Token::kASSIGN_INDEX)));
1020 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(3); 983 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(3);
1021 arguments->Add(receiver); 984 arguments->Add(receiver);
1022 arguments->Add(index); 985 arguments->Add(index);
1023 arguments->Add(new UseVal(incr)); 986 arguments->Add(new UseVal(incr));
1024 InstanceCallComp* store = new InstanceCallComp( 987 InstanceCallComp* store = new InstanceCallComp(
1025 node->token_index(), owner()->try_index(), 988 node->token_index(), owner()->try_index(),
1026 store_name, arguments, Array::ZoneHandle(), 1); 989 store_name, arguments, Array::ZoneHandle(), 1);
1027 DeallocateTempIndex(); // Consuming incr.
1028 DeallocateTempIndex(); // Consuming index.
1029 DeallocateTempIndex(); // Consuming receiver.
1030 AddInstruction(new DoInstr(store)); 990 AddInstruction(new DoInstr(store));
1031 ReturnValue(new UseVal(placeholder)); 991 ReturnValue(new UseVal(placeholder));
1032 } 992 }
1033 993
1034 994
1035 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 995 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
1036 TestGraphVisitor for_test(owner(), 996 TestGraphVisitor for_test(owner(),
1037 temp_index(), 997 temp_index(),
1038 node->condition()->token_index()); 998 node->condition()->token_index());
1039 node->condition()->Visit(&for_test); 999 node->condition()->Visit(&for_test);
(...skipping 12 matching lines...) Expand all
1052 TestGraphVisitor for_test(owner(), 1012 TestGraphVisitor for_test(owner(),
1053 temp_index(), 1013 temp_index(),
1054 node->condition()->token_index()); 1014 node->condition()->token_index());
1055 node->condition()->Visit(&for_test); 1015 node->condition()->Visit(&for_test);
1056 1016
1057 // Ensure that the value of the true/false subexpressions are named with 1017 // Ensure that the value of the true/false subexpressions are named with
1058 // the same temporary name. 1018 // the same temporary name.
1059 ValueGraphVisitor for_true(owner(), temp_index()); 1019 ValueGraphVisitor for_true(owner(), temp_index());
1060 node->true_expr()->Visit(&for_true); 1020 node->true_expr()->Visit(&for_true);
1061 ASSERT(for_true.is_open()); 1021 ASSERT(for_true.is_open());
1062 if (for_true.value()->IsTemp()) { 1022 ASSERT(for_true.value()->IsTemp() || for_true.value()->IsUse());
1063 ASSERT(for_true.value()->AsTemp()->index() == temp_index());
1064 } else {
1065 for_true.AddInstruction(new BindInstr(temp_index(), for_true.value()));
1066 }
1067 1023
1068 ValueGraphVisitor for_false(owner(), temp_index()); 1024 ValueGraphVisitor for_false(owner(), temp_index());
1069 node->false_expr()->Visit(&for_false); 1025 node->false_expr()->Visit(&for_false);
1070 ASSERT(for_false.is_open()); 1026 ASSERT(for_false.is_open());
1071 if (for_false.value()->IsTemp()) { 1027 ASSERT(for_false.value()->IsTemp() || for_false.value()->IsUse());
1072 ASSERT(for_false.value()->AsTemp()->index() == temp_index());
1073 } else {
1074 for_false.AddInstruction(new BindInstr(temp_index(), for_false.value()));
1075 }
1076 1028
1077 Join(for_test, for_true, for_false); 1029 Join(for_test, for_true, for_false);
1078 ReturnValue(new TempVal(AllocateTempIndex())); 1030 ReturnValue(new TempVal(temp_index() - 1));
1079 } 1031 }
1080 1032
1081 1033
1082 // <Statement> ::= If { condition: <Expression> 1034 // <Statement> ::= If { condition: <Expression>
1083 // true_branch: <Sequence> 1035 // true_branch: <Sequence>
1084 // false_branch: <Sequence> } 1036 // false_branch: <Sequence> }
1085 void EffectGraphVisitor::VisitIfNode(IfNode* node) { 1037 void EffectGraphVisitor::VisitIfNode(IfNode* node) {
1086 TestGraphVisitor for_test(owner(), 1038 TestGraphVisitor for_test(owner(),
1087 temp_index(), 1039 temp_index(),
1088 node->condition()->token_index()); 1040 node->condition()->token_index());
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
1470 1422
1471 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { 1423 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
1472 UNREACHABLE(); 1424 UNREACHABLE();
1473 } 1425 }
1474 1426
1475 1427
1476 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { 1428 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
1477 // Translate the array elements and collect their values. 1429 // Translate the array elements and collect their values.
1478 ZoneGrowableArray<Value*>* values = 1430 ZoneGrowableArray<Value*>* values =
1479 new ZoneGrowableArray<Value*>(node->length()); 1431 new ZoneGrowableArray<Value*>(node->length());
1480 int index = temp_index();
1481 for (int i = 0; i < node->length(); ++i) { 1432 for (int i = 0; i < node->length(); ++i) {
1482 ValueGraphVisitor for_value(owner(), index); 1433 ValueGraphVisitor for_value(owner(), temp_index());
1483 node->ElementAt(i)->Visit(&for_value); 1434 node->ElementAt(i)->Visit(&for_value);
1484 Append(for_value); 1435 Append(for_value);
1485 values->Add(for_value.value()); 1436 values->Add(for_value.value());
1486 index = for_value.temp_index();
1487 } 1437 }
1488 CreateArrayComp* create = new CreateArrayComp(node, 1438 CreateArrayComp* create = new CreateArrayComp(node,
1489 owner()->try_index(), 1439 owner()->try_index(),
1490 values); 1440 values);
1491 ReturnComputation(create); 1441 ReturnComputation(create);
1492 } 1442 }
1493 1443
1494 1444
1495 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { 1445 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
1496 const Function& function = node->function(); 1446 const Function& function = node->function();
1497 1447
1498 int next_index = temp_index();
1499 if (function.IsNonImplicitClosureFunction()) { 1448 if (function.IsNonImplicitClosureFunction()) {
1500 const ContextScope& context_scope = ContextScope::ZoneHandle( 1449 const ContextScope& context_scope = ContextScope::ZoneHandle(
1501 node->scope()->PreserveOuterScope(owner()->context_level())); 1450 node->scope()->PreserveOuterScope(owner()->context_level()));
1502 ASSERT(!function.HasCode()); 1451 ASSERT(!function.HasCode());
1503 ASSERT(function.context_scope() == ContextScope::null()); 1452 ASSERT(function.context_scope() == ContextScope::null());
1504 function.set_context_scope(context_scope); 1453 function.set_context_scope(context_scope);
1505 } else if (function.IsImplicitInstanceClosureFunction()) { 1454 } else if (function.IsImplicitInstanceClosureFunction()) {
1506 ValueGraphVisitor for_receiver(owner(), temp_index()); 1455 ValueGraphVisitor for_receiver(owner(), temp_index());
1507 node->receiver()->Visit(&for_receiver); 1456 node->receiver()->Visit(&for_receiver);
1508 Append(for_receiver); 1457 Append(for_receiver);
1509 if (!for_receiver.value()->IsTemp()) {
1510 AddInstruction(new BindInstr(temp_index(), for_receiver.value()));
1511 }
1512 ++next_index;
1513 } 1458 }
1514 ASSERT(function.context_scope() != ContextScope::null()); 1459 ASSERT(function.context_scope() != ContextScope::null());
1515 1460
1516 // The function type of a closure may have type arguments. In that case, pass 1461 // The function type of a closure may have type arguments. In that case, pass
1517 // the type arguments of the instantiator. 1462 // the type arguments of the instantiator.
1518 const Class& cls = Class::Handle(function.signature_class()); 1463 const Class& cls = Class::Handle(function.signature_class());
1519 ASSERT(!cls.IsNull()); 1464 ASSERT(!cls.IsNull());
1520 const bool requires_type_arguments = cls.HasTypeArguments(); 1465 const bool requires_type_arguments = cls.HasTypeArguments();
1521 Value* type_arguments = NULL; 1466 Value* type_arguments = NULL;
1522 if (requires_type_arguments) { 1467 if (requires_type_arguments) {
1523 ASSERT(!function.IsImplicitStaticClosureFunction()); 1468 ASSERT(!function.IsImplicitStaticClosureFunction());
1524 type_arguments = 1469 type_arguments =
1525 BuildInstantiatorTypeArguments(node->token_index(), temp_index()); 1470 BuildInstantiatorTypeArguments(node->token_index());
1526 } 1471 }
1527 1472
1528 CreateClosureComp* create = 1473 CreateClosureComp* create =
1529 new CreateClosureComp(node, owner()->try_index(), type_arguments); 1474 new CreateClosureComp(node, owner()->try_index(), type_arguments);
1530 ReturnComputation(create); 1475 ReturnComputation(create);
1531 } 1476 }
1532 1477
1533 1478
1534 void EffectGraphVisitor::TranslateArgumentList( 1479 void EffectGraphVisitor::TranslateArgumentList(
1535 const ArgumentListNode& node, 1480 const ArgumentListNode& node,
1536 intptr_t next_temp_index,
1537 ZoneGrowableArray<Value*>* values) { 1481 ZoneGrowableArray<Value*>* values) {
1538 for (intptr_t i = 0; i < node.length(); ++i) { 1482 for (intptr_t i = 0; i < node.length(); ++i) {
1539 ValueGraphVisitor for_argument(owner(), next_temp_index); 1483 ValueGraphVisitor for_argument(owner(), temp_index());
1540 node.NodeAt(i)->Visit(&for_argument); 1484 node.NodeAt(i)->Visit(&for_argument);
1541 Append(for_argument); 1485 Append(for_argument);
1542 next_temp_index = for_argument.temp_index();
1543 values->Add(for_argument.value()); 1486 values->Add(for_argument.value());
1544 } 1487 }
1545 } 1488 }
1546 1489
1547 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { 1490 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
1548 ArgumentListNode* arguments = node->arguments(); 1491 ArgumentListNode* arguments = node->arguments();
1549 int length = arguments->length(); 1492 int length = arguments->length();
1550 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length + 1); 1493 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length + 1);
1551 1494
1552 ValueGraphVisitor for_receiver(owner(), temp_index()); 1495 ValueGraphVisitor for_receiver(owner(), temp_index());
1553 node->receiver()->Visit(&for_receiver); 1496 node->receiver()->Visit(&for_receiver);
1554 Append(for_receiver); 1497 Append(for_receiver);
1555 values->Add(for_receiver.value()); 1498 values->Add(for_receiver.value());
1556 1499
1557 TranslateArgumentList(*arguments, for_receiver.temp_index(), values); 1500 TranslateArgumentList(*arguments, values);
1558 InstanceCallComp* call = new InstanceCallComp( 1501 InstanceCallComp* call = new InstanceCallComp(
1559 node->token_index(), owner()->try_index(), 1502 node->token_index(), owner()->try_index(),
1560 node->function_name(), values, 1503 node->function_name(), values,
1561 arguments->names(), 1); 1504 arguments->names(), 1);
1562 ReturnComputation(call); 1505 ReturnComputation(call);
1563 } 1506 }
1564 1507
1565 1508
1566 // <Expression> ::= StaticCall { function: Function 1509 // <Expression> ::= StaticCall { function: Function
1567 // arguments: <ArgumentList> } 1510 // arguments: <ArgumentList> }
1568 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { 1511 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
1569 int length = node->arguments()->length(); 1512 int length = node->arguments()->length();
1570 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length); 1513 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length);
1571 TranslateArgumentList(*node->arguments(), temp_index(), values); 1514 TranslateArgumentList(*node->arguments(), values);
1572 StaticCallComp* call = 1515 StaticCallComp* call =
1573 new StaticCallComp(node->token_index(), 1516 new StaticCallComp(node->token_index(),
1574 owner()->try_index(), 1517 owner()->try_index(),
1575 node->function(), 1518 node->function(),
1576 node->arguments()->names(), 1519 node->arguments()->names(),
1577 values); 1520 values);
1578 ReturnComputation(call); 1521 ReturnComputation(call);
1579 } 1522 }
1580 1523
1581 1524
1582 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 1525 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
1583 // Context is saved around the call, it's treated as an extra operand 1526 // Context is saved around the call, it's treated as an extra operand
1584 // consumed by the call (but not an argument). 1527 // consumed by the call (but not an argument).
1585 BindInstr* context = new BindInstr(temp_index(), new CurrentContextComp()); 1528 BindInstr* context = new BindInstr(new CurrentContextComp());
1586 AddInstruction(context); 1529 AddInstruction(context);
1587 1530
1588 ValueGraphVisitor for_closure(owner(), temp_index() + 1); 1531 ValueGraphVisitor for_closure(owner(), temp_index());
1589 node->closure()->Visit(&for_closure); 1532 node->closure()->Visit(&for_closure);
1590 Append(for_closure); 1533 Append(for_closure);
1591 1534
1592 ZoneGrowableArray<Value*>* arguments = 1535 ZoneGrowableArray<Value*>* arguments =
1593 new ZoneGrowableArray<Value*>(node->arguments()->length()); 1536 new ZoneGrowableArray<Value*>(node->arguments()->length());
1594 arguments->Add(for_closure.value()); 1537 arguments->Add(for_closure.value());
1595 TranslateArgumentList(*node->arguments(), temp_index() + 2, arguments); 1538 TranslateArgumentList(*node->arguments(), arguments);
1596 // First operand is the saved context, consumed by the call. 1539 // First operand is the saved context, consumed by the call.
1597 ClosureCallComp* call = new ClosureCallComp(node, 1540 ClosureCallComp* call = new ClosureCallComp(node,
1598 owner()->try_index(), 1541 owner()->try_index(),
1599 new UseVal(context), 1542 new UseVal(context),
1600 arguments); 1543 arguments);
1601 ReturnComputation(call); 1544 ReturnComputation(call);
1602 } 1545 }
1603 1546
1604 1547
1605 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { 1548 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
1606 BindInstr* context = new BindInstr(temp_index(), new CurrentContextComp()); 1549 BindInstr* context = new BindInstr(new CurrentContextComp());
1607 AddInstruction(context); 1550 AddInstruction(context);
1608 BindInstr* clone = 1551 BindInstr* clone =
1609 new BindInstr(temp_index(), 1552 new BindInstr(new CloneContextComp(node->token_index(),
1610 new CloneContextComp(node->token_index(),
1611 owner()->try_index(), 1553 owner()->try_index(),
1612 new UseVal(context))); 1554 new UseVal(context)));
1613 AddInstruction(clone); 1555 AddInstruction(clone);
1614 ReturnComputation(new StoreContextComp(new UseVal(clone))); 1556 ReturnComputation(new StoreContextComp(new UseVal(clone)));
1615 } 1557 }
1616 1558
1617 1559
1618 Definition* EffectGraphVisitor::BuildObjectAllocation( 1560 Definition* EffectGraphVisitor::BuildObjectAllocation(
1619 ConstructorCallNode* node) { 1561 ConstructorCallNode* node) {
1620 const Class& cls = Class::ZoneHandle(node->constructor().owner()); 1562 const Class& cls = Class::ZoneHandle(node->constructor().owner());
(...skipping 21 matching lines...) Expand all
1642 // may represent the identity vector and may be replaced by the instantiated 1584 // may represent the identity vector and may be replaced by the instantiated
1643 // type arguments of the instantiator at run time. 1585 // type arguments of the instantiator at run time.
1644 allocate_comp = new AllocateObjectWithBoundsCheckComp(node, 1586 allocate_comp = new AllocateObjectWithBoundsCheckComp(node,
1645 owner()->try_index(), 1587 owner()->try_index(),
1646 allocate_arguments); 1588 allocate_arguments);
1647 } else { 1589 } else {
1648 allocate_comp = new AllocateObjectComp(node, 1590 allocate_comp = new AllocateObjectComp(node,
1649 owner()->try_index(), 1591 owner()->try_index(),
1650 allocate_arguments); 1592 allocate_arguments);
1651 } 1593 }
1652 BindInstr* allocate = new BindInstr(temp_index(), allocate_comp); 1594 BindInstr* allocate = new BindInstr(allocate_comp);
1653 AddInstruction(allocate); 1595 AddInstruction(allocate);
1654 AllocateTempIndex();
1655 return allocate; 1596 return allocate;
1656 } 1597 }
1657 1598
1658 1599
1659 void EffectGraphVisitor::BuildConstructorCall(ConstructorCallNode* node, 1600 void EffectGraphVisitor::BuildConstructorCall(ConstructorCallNode* node,
1660 Value* alloc_value) { 1601 Value* alloc_value) {
1661 BindInstr* ctor_arg = 1602 BindInstr* ctor_arg =
1662 new BindInstr(temp_index(), 1603 new BindInstr(new ConstantVal(
1663 new ConstantVal(
1664 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); 1604 Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))));
1665 AddInstruction(ctor_arg); 1605 AddInstruction(ctor_arg);
1666 AllocateTempIndex();
1667 1606
1668 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(); 1607 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>();
1669 values->Add(alloc_value); 1608 values->Add(alloc_value);
1670 values->Add(new UseVal(ctor_arg)); 1609 values->Add(new UseVal(ctor_arg));
1671 1610
1672 TranslateArgumentList(*node->arguments(), temp_index(), values); 1611 TranslateArgumentList(*node->arguments(), values);
1673 StaticCallComp* call = 1612 StaticCallComp* call =
1674 new StaticCallComp(node->token_index(), 1613 new StaticCallComp(node->token_index(),
1675 owner()->try_index(), 1614 owner()->try_index(),
1676 node->constructor(), 1615 node->constructor(),
1677 node->arguments()->names(), 1616 node->arguments()->names(),
1678 values); 1617 values);
1679 DeallocateTempIndex(); // Consuming ctor_arg.
1680 DeallocateTempIndex(); // Consuming alloc_value.
1681 AddInstruction(new DoInstr(call)); 1618 AddInstruction(new DoInstr(call));
1682 } 1619 }
1683 1620
1684 1621
1685 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 1622 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
1686 if (node->constructor().IsFactory()) { 1623 if (node->constructor().IsFactory()) {
1687 ZoneGrowableArray<Value*>* factory_arguments = 1624 ZoneGrowableArray<Value*>* factory_arguments =
1688 new ZoneGrowableArray<Value*>(); 1625 new ZoneGrowableArray<Value*>();
1689 factory_arguments->Add(new UseVal(BuildFactoryTypeArguments(node))); 1626 factory_arguments->Add(new UseVal(BuildFactoryTypeArguments(node)));
1690 ASSERT(factory_arguments->length() == 1); 1627 ASSERT(factory_arguments->length() == 1);
1691 TranslateArgumentList(*node->arguments(), 1628 TranslateArgumentList(*node->arguments(), factory_arguments);
1692 temp_index(),
1693 factory_arguments);
1694 StaticCallComp* call = 1629 StaticCallComp* call =
1695 new StaticCallComp(node->token_index(), 1630 new StaticCallComp(node->token_index(),
1696 owner()->try_index(), 1631 owner()->try_index(),
1697 node->constructor(), 1632 node->constructor(),
1698 node->arguments()->names(), 1633 node->arguments()->names(),
1699 factory_arguments); 1634 factory_arguments);
1700 DeallocateTempIndex(); // Consuming type arguments.
1701 ReturnComputation(call); 1635 ReturnComputation(call);
1702 return; 1636 return;
1703 } 1637 }
1704 // t_n contains the allocated and initialized object. 1638 // t_n contains the allocated and initialized object.
1705 // t_n <- AllocateObject(class) 1639 // t_n <- AllocateObject(class)
1706 // t_n+1 <- ctor-arg 1640 // t_n+1 <- ctor-arg
1707 // t_n+2... <- constructor arguments start here 1641 // t_n+2... <- constructor arguments start here
1708 // StaticCall(constructor, t_n+1, t_n+2, ...) 1642 // StaticCall(constructor, t_n+1, t_n+2, ...)
1709 // No need to preserve allocated value (simpler than in ValueGraphVisitor). 1643 // No need to preserve allocated value (simpler than in ValueGraphVisitor).
1710 Definition* allocate = BuildObjectAllocation(node); 1644 Definition* allocate = BuildObjectAllocation(node);
1711 BuildConstructorCall(node, new UseVal(allocate)); 1645 BuildConstructorCall(node, new UseVal(allocate));
1712 } 1646 }
1713 1647
1714 1648
1715 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( 1649 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments(
1716 intptr_t token_index, intptr_t start_index) { 1650 intptr_t token_index) {
1717 const Class& instantiator_class = Class::Handle( 1651 const Class& instantiator_class = Class::Handle(
1718 owner()->parsed_function().function().owner()); 1652 owner()->parsed_function().function().owner());
1719 if (instantiator_class.NumTypeParameters() == 0) { 1653 if (instantiator_class.NumTypeParameters() == 0) {
1720 // The type arguments are compile time constants. 1654 // The type arguments are compile time constants.
1721 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle(); 1655 AbstractTypeArguments& type_arguments = AbstractTypeArguments::ZoneHandle();
1722 // TODO(regis): Temporary type should be allocated in new gen heap. 1656 // TODO(regis): Temporary type should be allocated in new gen heap.
1723 Type& type = Type::Handle( 1657 Type& type = Type::Handle(
1724 Type::New(instantiator_class, type_arguments, token_index)); 1658 Type::New(instantiator_class, type_arguments, token_index));
1725 type ^= ClassFinalizer::FinalizeType( 1659 type ^= ClassFinalizer::FinalizeType(
1726 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed); 1660 instantiator_class, type, ClassFinalizer::kFinalizeWellFormed);
1727 type_arguments = type.arguments(); 1661 type_arguments = type.arguments();
1728 BindInstr* args = 1662 BindInstr* args = new BindInstr(new ConstantVal(type_arguments));
1729 new BindInstr(temp_index(), new ConstantVal(type_arguments));
1730 AddInstruction(args); 1663 AddInstruction(args);
1731 return new UseVal(args); 1664 return new UseVal(args);
1732 } 1665 }
1733 ASSERT(owner()->parsed_function().instantiator() != NULL); 1666 ASSERT(owner()->parsed_function().instantiator() != NULL);
1734 ValueGraphVisitor for_instantiator(owner(), start_index); 1667 ValueGraphVisitor for_instantiator(owner(), temp_index());
1735 owner()->parsed_function().instantiator()->Visit(&for_instantiator); 1668 owner()->parsed_function().instantiator()->Visit(&for_instantiator);
1736 Append(for_instantiator); 1669 Append(for_instantiator);
1737 Function& outer_function = 1670 Function& outer_function =
1738 Function::Handle(owner()->parsed_function().function().raw()); 1671 Function::Handle(owner()->parsed_function().function().raw());
1739 while (outer_function.IsLocalFunction()) { 1672 while (outer_function.IsLocalFunction()) {
1740 outer_function = outer_function.parent_function(); 1673 outer_function = outer_function.parent_function();
1741 } 1674 }
1742 if (outer_function.IsFactory()) { 1675 if (outer_function.IsFactory()) {
1743 // All OK. 1676 // All OK.
1744 return for_instantiator.value(); 1677 return for_instantiator.value();
1745 } 1678 }
1746 1679
1747 // The instantiator is the receiver of the caller, which is not a factory. 1680 // The instantiator is the receiver of the caller, which is not a factory.
1748 // The receiver cannot be null; extract its AbstractTypeArguments object. 1681 // The receiver cannot be null; extract its AbstractTypeArguments object.
1749 // Note that in the factory case, the instantiator is the first parameter 1682 // Note that in the factory case, the instantiator is the first parameter
1750 // of the factory, i.e. already an AbstractTypeArguments object. 1683 // of the factory, i.e. already an AbstractTypeArguments object.
1751 intptr_t type_arguments_instance_field_offset = 1684 intptr_t type_arguments_instance_field_offset =
1752 instantiator_class.type_arguments_instance_field_offset(); 1685 instantiator_class.type_arguments_instance_field_offset();
1753 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments); 1686 ASSERT(type_arguments_instance_field_offset != Class::kNoTypeArguments);
1754 1687
1755 BindInstr* load = 1688 BindInstr* load =
1756 new BindInstr(start_index, 1689 new BindInstr(new NativeLoadFieldComp(
1757 new NativeLoadFieldComp(
1758 for_instantiator.value(), 1690 for_instantiator.value(),
1759 type_arguments_instance_field_offset)); 1691 type_arguments_instance_field_offset));
1760 AddInstruction(load); 1692 AddInstruction(load);
1761 return new UseVal(load); 1693 return new UseVal(load);
1762 } 1694 }
1763 1695
1764 1696
1765 Definition* EffectGraphVisitor::BuildFactoryTypeArguments( 1697 Definition* EffectGraphVisitor::BuildFactoryTypeArguments(
1766 ConstructorCallNode* node) { 1698 ConstructorCallNode* node) {
1767 ASSERT(node->constructor().IsFactory()); 1699 ASSERT(node->constructor().IsFactory());
1768 if (node->type_arguments().IsNull() || 1700 if (node->type_arguments().IsNull() ||
1769 node->type_arguments().IsInstantiated()) { 1701 node->type_arguments().IsInstantiated()) {
1770 BindInstr* type_args = 1702 BindInstr* type_args =
1771 new BindInstr(temp_index(), new ConstantVal(node->type_arguments())); 1703 new BindInstr(new ConstantVal(node->type_arguments()));
1772 AddInstruction(type_args); 1704 AddInstruction(type_args);
1773 AllocateTempIndex();
1774 return type_args; 1705 return type_args;
1775 } 1706 }
1776 // The type arguments are uninstantiated. 1707 // The type arguments are uninstantiated.
1777 Value* instantiator_value = 1708 Value* instantiator_value =
1778 BuildInstantiatorTypeArguments(node->token_index(), temp_index()); 1709 BuildInstantiatorTypeArguments(node->token_index());
1779 BindInstr* extract = 1710 BindInstr* extract =
1780 new BindInstr(temp_index(), 1711 new BindInstr(new ExtractFactoryTypeArgumentsComp(node,
1781 new ExtractFactoryTypeArgumentsComp(node,
1782 owner()->try_index(), 1712 owner()->try_index(),
1783 instantiator_value)); 1713 instantiator_value));
1784 AddInstruction(extract); 1714 AddInstruction(extract);
1785 AllocateTempIndex();
1786 return extract; 1715 return extract;
1787 } 1716 }
1788 1717
1789 1718
1790 void EffectGraphVisitor::BuildConstructorTypeArguments( 1719 void EffectGraphVisitor::BuildConstructorTypeArguments(
1791 ConstructorCallNode* node, 1720 ConstructorCallNode* node,
1792 ZoneGrowableArray<Value*>* args) { 1721 ZoneGrowableArray<Value*>* args) {
1793 const Class& cls = Class::ZoneHandle(node->constructor().owner()); 1722 const Class& cls = Class::ZoneHandle(node->constructor().owner());
1794 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory()); 1723 ASSERT(cls.HasTypeArguments() && !node->constructor().IsFactory());
1795 if (node->type_arguments().IsNull() || 1724 if (node->type_arguments().IsNull() ||
1796 node->type_arguments().IsInstantiated()) { 1725 node->type_arguments().IsInstantiated()) {
1797 BindInstr* type_args = 1726 BindInstr* type_args =
1798 new BindInstr(temp_index(), new ConstantVal(node->type_arguments())); 1727 new BindInstr(new ConstantVal(node->type_arguments()));
1799 AddInstruction(type_args); 1728 AddInstruction(type_args);
1800 // No instantiator required. 1729 // No instantiator required.
1801 BindInstr* no_instantiator = 1730 BindInstr* no_instantiator =
1802 new BindInstr(temp_index() + 1, 1731 new BindInstr(new ConstantVal(
1803 new ConstantVal(
1804 Smi::ZoneHandle(Smi::New( 1732 Smi::ZoneHandle(Smi::New(
1805 StubCode::kNoInstantiator)))); 1733 StubCode::kNoInstantiator))));
1806 AddInstruction(no_instantiator); 1734 AddInstruction(no_instantiator);
1807 args->Add(new UseVal(type_args)); 1735 args->Add(new UseVal(type_args));
1808 args->Add(new UseVal(no_instantiator)); 1736 args->Add(new UseVal(no_instantiator));
1809 return; 1737 return;
1810 } 1738 }
1811 // The type arguments are uninstantiated. 1739 // The type arguments are uninstantiated.
1812 // Place holder to hold uninstantiated constructor type arguments. 1740 // Place holder to hold uninstantiated constructor type arguments.
1813 BindInstr* placeholder = 1741 BindInstr* placeholder =
1814 new BindInstr(temp_index(), 1742 new BindInstr(new ConstantVal(Object::ZoneHandle()));
1815 new ConstantVal(Object::ZoneHandle()));
1816 AddInstruction(placeholder); 1743 AddInstruction(placeholder);
1817 Value* instantiator = 1744 Value* instantiator =
1818 BuildInstantiatorTypeArguments(node->token_index(), temp_index() + 1); 1745 BuildInstantiatorTypeArguments(node->token_index());
1819 ASSERT(instantiator->IsUse()); 1746 ASSERT(instantiator->IsUse());
1820 PickTempInstr* duplicate_instantiator = 1747 PickTempInstr* duplicate_instantiator =
1821 new PickTempInstr(temp_index() + 2, 1748 new PickTempInstr(instantiator->AsUse()->definition()->temp_index());
1822 instantiator->AsUse()->definition()->temp_index());
1823 AddInstruction(duplicate_instantiator); 1749 AddInstruction(duplicate_instantiator);
1824 BindInstr* extract_type_arguments = 1750 BindInstr* extract_type_arguments =
1825 new BindInstr(temp_index() + 2, 1751 new BindInstr(new ExtractConstructorTypeArgumentsComp(
1826 new ExtractConstructorTypeArgumentsComp(
1827 node, new UseVal(duplicate_instantiator))); 1752 node, new UseVal(duplicate_instantiator)));
1828 AddInstruction(extract_type_arguments); 1753 AddInstruction(extract_type_arguments);
1829 AddInstruction(new TuckTempInstr(placeholder->temp_index(), 1754 AddInstruction(new TuckTempInstr(placeholder->temp_index(),
1830 extract_type_arguments->temp_index())); 1755 extract_type_arguments->temp_index()));
1831 BindInstr* extract_instantiator = 1756 BindInstr* extract_instantiator =
1832 new BindInstr(temp_index() + 1, 1757 new BindInstr(new ExtractConstructorInstantiatorComp(
1833 new ExtractConstructorInstantiatorComp(
1834 node, 1758 node,
1835 instantiator, 1759 instantiator,
1836 new UseVal(extract_type_arguments))); 1760 new UseVal(extract_type_arguments)));
1837 AddInstruction(extract_instantiator); 1761 AddInstruction(extract_instantiator);
1838 args->Add(new UseVal(placeholder)); 1762 args->Add(new UseVal(placeholder));
1839 args->Add(new UseVal(extract_instantiator)); 1763 args->Add(new UseVal(extract_instantiator));
1840 } 1764 }
1841 1765
1842 1766
1843 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 1767 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
1844 if (node->constructor().IsFactory()) { 1768 if (node->constructor().IsFactory()) {
1845 EffectGraphVisitor::VisitConstructorCallNode(node); 1769 EffectGraphVisitor::VisitConstructorCallNode(node);
1846 return; 1770 return;
1847 } 1771 }
1848 1772
1849 // t_n contains the allocated and initialized object. 1773 // t_n contains the allocated and initialized object.
1850 // t_n <- AllocateObject(class) 1774 // t_n <- AllocateObject(class)
1851 // t_n+1 <- Pick(t_n) 1775 // t_n+1 <- Pick(t_n)
1852 // t_n+2 <- ctor-arg 1776 // t_n+2 <- ctor-arg
1853 // t_n+3... <- constructor arguments start here 1777 // t_n+3... <- constructor arguments start here
1854 // StaticCall(constructor, t_n+1, t_n+2, ...) 1778 // StaticCall(constructor, t_n+1, t_n+2, ...)
1855 1779
1856 Definition* allocate = BuildObjectAllocation(node); 1780 Definition* allocate = BuildObjectAllocation(node);
1857 PickTempInstr* duplicate = 1781 PickTempInstr* duplicate = new PickTempInstr(allocate->temp_index());
1858 new PickTempInstr(temp_index(), allocate->temp_index());
1859 AddInstruction(duplicate); 1782 AddInstruction(duplicate);
1860 AllocateTempIndex();
1861 BuildConstructorCall(node, new UseVal(duplicate)); 1783 BuildConstructorCall(node, new UseVal(duplicate));
1862 ReturnValue(new UseVal(allocate)); 1784 ReturnValue(new UseVal(allocate));
1863 } 1785 }
1864 1786
1865 1787
1866 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { 1788 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
1867 ValueGraphVisitor for_receiver(owner(), temp_index()); 1789 ValueGraphVisitor for_receiver(owner(), temp_index());
1868 node->receiver()->Visit(&for_receiver); 1790 node->receiver()->Visit(&for_receiver);
1869 Append(for_receiver); 1791 Append(for_receiver);
1870 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1); 1792 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(1);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1963 // value: <Expression> } 1885 // value: <Expression> }
1964 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { 1886 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
1965 ValueGraphVisitor for_value(owner(), temp_index()); 1887 ValueGraphVisitor for_value(owner(), temp_index());
1966 node->value()->Visit(&for_value); 1888 node->value()->Visit(&for_value);
1967 Append(for_value); 1889 Append(for_value);
1968 Value* store_value = for_value.value(); 1890 Value* store_value = for_value.value();
1969 if (FLAG_enable_type_checks) { 1891 if (FLAG_enable_type_checks) {
1970 store_value = BuildAssignableValue(node->value(), 1892 store_value = BuildAssignableValue(node->value(),
1971 store_value, 1893 store_value,
1972 node->local().type(), 1894 node->local().type(),
1973 node->local().name(), 1895 node->local().name());
1974 temp_index());
1975 } 1896 }
1976 StoreLocalComp* store = 1897 StoreLocalComp* store =
1977 new StoreLocalComp(node->local(), store_value, owner()->context_level()); 1898 new StoreLocalComp(node->local(), store_value, owner()->context_level());
1978 ReturnComputation(store); 1899 ReturnComputation(store);
1979 } 1900 }
1980 1901
1981 1902
1982 void EffectGraphVisitor::VisitLoadInstanceFieldNode( 1903 void EffectGraphVisitor::VisitLoadInstanceFieldNode(
1983 LoadInstanceFieldNode* node) { 1904 LoadInstanceFieldNode* node) {
1984 ValueGraphVisitor for_instance(owner(), temp_index()); 1905 ValueGraphVisitor for_instance(owner(), temp_index());
(...skipping 13 matching lines...) Expand all
1998 ValueGraphVisitor for_value(owner(), for_instance.temp_index()); 1919 ValueGraphVisitor for_value(owner(), for_instance.temp_index());
1999 node->value()->Visit(&for_value); 1920 node->value()->Visit(&for_value);
2000 Append(for_value); 1921 Append(for_value);
2001 Value* store_value = for_value.value(); 1922 Value* store_value = for_value.value();
2002 if (FLAG_enable_type_checks) { 1923 if (FLAG_enable_type_checks) {
2003 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); 1924 const AbstractType& type = AbstractType::ZoneHandle(node->field().type());
2004 const String& dst_name = String::ZoneHandle(node->field().name()); 1925 const String& dst_name = String::ZoneHandle(node->field().name());
2005 store_value = BuildAssignableValue(node->value(), 1926 store_value = BuildAssignableValue(node->value(),
2006 store_value, 1927 store_value,
2007 type, 1928 type,
2008 dst_name, 1929 dst_name);
2009 for_instance.temp_index());
2010 } 1930 }
2011 StoreInstanceFieldComp* store = 1931 StoreInstanceFieldComp* store =
2012 new StoreInstanceFieldComp(node, for_instance.value(), store_value); 1932 new StoreInstanceFieldComp(node, for_instance.value(), store_value);
2013 ReturnComputation(store); 1933 ReturnComputation(store);
2014 } 1934 }
2015 1935
2016 1936
2017 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { 1937 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
2018 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field()); 1938 LoadStaticFieldComp* load = new LoadStaticFieldComp(node->field());
2019 ReturnComputation(load); 1939 ReturnComputation(load);
2020 } 1940 }
2021 1941
2022 1942
2023 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { 1943 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
2024 ValueGraphVisitor for_value(owner(), temp_index()); 1944 ValueGraphVisitor for_value(owner(), temp_index());
2025 node->value()->Visit(&for_value); 1945 node->value()->Visit(&for_value);
2026 Append(for_value); 1946 Append(for_value);
2027 Value* store_value = for_value.value(); 1947 Value* store_value = for_value.value();
2028 if (FLAG_enable_type_checks) { 1948 if (FLAG_enable_type_checks) {
2029 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); 1949 const AbstractType& type = AbstractType::ZoneHandle(node->field().type());
2030 const String& dst_name = String::ZoneHandle(node->field().name()); 1950 const String& dst_name = String::ZoneHandle(node->field().name());
2031 store_value = BuildAssignableValue(node->value(), 1951 store_value = BuildAssignableValue(node->value(),
2032 store_value, 1952 store_value,
2033 type, 1953 type,
2034 dst_name, 1954 dst_name);
2035 temp_index());
2036 } 1955 }
2037 StoreStaticFieldComp* store = 1956 StoreStaticFieldComp* store =
2038 new StoreStaticFieldComp(node->field(), store_value); 1957 new StoreStaticFieldComp(node->field(), store_value);
2039 ReturnComputation(store); 1958 ReturnComputation(store);
2040 } 1959 }
2041 1960
2042 1961
2043 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { 1962 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
2044 ValueGraphVisitor for_array(owner(), temp_index()); 1963 ValueGraphVisitor for_array(owner(), temp_index());
2045 node->array()->Visit(&for_array); 1964 node->array()->Visit(&for_array);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2078 } 1997 }
2079 1998
2080 1999
2081 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { 2000 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const {
2082 return (node == owner()->parsed_function().node_sequence()) && 2001 return (node == owner()->parsed_function().node_sequence()) &&
2083 (owner()->parsed_function().saved_context_var() != NULL); 2002 (owner()->parsed_function().saved_context_var() != NULL);
2084 } 2003 }
2085 2004
2086 2005
2087 void EffectGraphVisitor::UnchainContext() { 2006 void EffectGraphVisitor::UnchainContext() {
2088 BindInstr* context = new BindInstr(temp_index(), new CurrentContextComp()); 2007 BindInstr* context = new BindInstr(new CurrentContextComp());
2089 AddInstruction(context); 2008 AddInstruction(context);
2090 BindInstr* parent = 2009 BindInstr* parent =
2091 new BindInstr(temp_index(), 2010 new BindInstr(new NativeLoadFieldComp(
2092 new NativeLoadFieldComp(
2093 new UseVal(context), Context::parent_offset())); 2011 new UseVal(context), Context::parent_offset()));
2094 AddInstruction(parent); 2012 AddInstruction(parent);
2095 AddInstruction(new DoInstr(new StoreContextComp(new UseVal(parent)))); 2013 AddInstruction(new DoInstr(new StoreContextComp(new UseVal(parent))));
2096 } 2014 }
2097 2015
2098 2016
2099 // <Statement> ::= Sequence { scope: LocalScope 2017 // <Statement> ::= Sequence { scope: LocalScope
2100 // nodes: <Statement>* 2018 // nodes: <Statement>*
2101 // label: SourceLabel } 2019 // label: SourceLabel }
2102 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { 2020 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) {
2103 LocalScope* scope = node->scope(); 2021 LocalScope* scope = node->scope();
2104 const intptr_t num_context_variables = 2022 const intptr_t num_context_variables =
2105 (scope != NULL) ? scope->num_context_variables() : 0; 2023 (scope != NULL) ? scope->num_context_variables() : 0;
2106 int previous_context_level = owner()->context_level(); 2024 int previous_context_level = owner()->context_level();
2107 if (num_context_variables > 0) { 2025 if (num_context_variables > 0) {
2108 // The loop local scope declares variables that are captured. 2026 // The loop local scope declares variables that are captured.
2109 // Allocate and chain a new context. 2027 // Allocate and chain a new context.
2110 // Allocate context computation (uses current CTX) 2028 // Allocate context computation (uses current CTX)
2111 BindInstr* allocated_context = 2029 BindInstr* allocated_context =
2112 new BindInstr(temp_index(), 2030 new BindInstr(new AllocateContextComp(node->token_index(),
2113 new AllocateContextComp(node->token_index(),
2114 owner()->try_index(), 2031 owner()->try_index(),
2115 num_context_variables)); 2032 num_context_variables));
2116 AddInstruction(allocated_context); 2033 AddInstruction(allocated_context);
2117 2034
2118 // If this node_sequence is the body of the function being compiled, and if 2035 // If this node_sequence is the body of the function being compiled, and if
2119 // this function is not a closure, do not link the current context as the 2036 // this function is not a closure, do not link the current context as the
2120 // parent of the newly allocated context, as it is not accessible. Instead, 2037 // parent of the newly allocated context, as it is not accessible. Instead,
2121 // save it in a pre-allocated variable and restore it on exit. 2038 // save it in a pre-allocated variable and restore it on exit.
2122 if (MustSaveRestoreContext(node)) { 2039 if (MustSaveRestoreContext(node)) {
2123 BindInstr* current_context = 2040 BindInstr* current_context = new BindInstr(new CurrentContextComp());
2124 new BindInstr(temp_index() + 1, new CurrentContextComp());
2125 AddInstruction(current_context); 2041 AddInstruction(current_context);
2126 StoreLocalComp* store_local = new StoreLocalComp( 2042 StoreLocalComp* store_local = new StoreLocalComp(
2127 *owner()->parsed_function().saved_context_var(), 2043 *owner()->parsed_function().saved_context_var(),
2128 new UseVal(current_context), 2044 new UseVal(current_context),
2129 0); 2045 0);
2130 AddInstruction(new DoInstr(store_local)); 2046 AddInstruction(new DoInstr(store_local));
2131 BindInstr* null_context = 2047 BindInstr* null_context =
2132 new BindInstr(temp_index() + 1, 2048 new BindInstr(new ConstantVal(Object::ZoneHandle()));
2133 new ConstantVal(Object::ZoneHandle()));
2134 AddInstruction(null_context); 2049 AddInstruction(null_context);
2135 StoreContextComp* store_context = 2050 StoreContextComp* store_context =
2136 new StoreContextComp(new UseVal(null_context)); 2051 new StoreContextComp(new UseVal(null_context));
2137 AddInstruction(new DoInstr(store_context)); 2052 AddInstruction(new DoInstr(store_context));
2138 } 2053 }
2139 2054
2140 ChainContextComp* chain_context = 2055 ChainContextComp* chain_context =
2141 new ChainContextComp(new UseVal(allocated_context)); 2056 new ChainContextComp(new UseVal(allocated_context));
2142 AddInstruction(new DoInstr(chain_context)); 2057 AddInstruction(new DoInstr(chain_context));
2143 owner()->set_context_level(scope->context_level()); 2058 owner()->set_context_level(scope->context_level());
(...skipping 14 matching lines...) Expand all
2158 const String& temp_name = String::ZoneHandle(String::Concat( 2073 const String& temp_name = String::ZoneHandle(String::Concat(
2159 parameter.name(), String::Handle(String::NewSymbol("-orig")))); 2074 parameter.name(), String::Handle(String::NewSymbol("-orig"))));
2160 LocalVariable* temp_local = new LocalVariable( 2075 LocalVariable* temp_local = new LocalVariable(
2161 0, // Token index. 2076 0, // Token index.
2162 temp_name, 2077 temp_name,
2163 Type::ZoneHandle(Type::DynamicType())); // Type. 2078 Type::ZoneHandle(Type::DynamicType())); // Type.
2164 temp_local->set_index(param_frame_index); 2079 temp_local->set_index(param_frame_index);
2165 2080
2166 // Copy parameter from local frame to current context. 2081 // Copy parameter from local frame to current context.
2167 BindInstr* load = 2082 BindInstr* load =
2168 new BindInstr(temp_index(), 2083 new BindInstr(new LoadLocalComp(*temp_local,
2169 new LoadLocalComp(*temp_local,
2170 owner()->context_level())); 2084 owner()->context_level()));
2171 AddInstruction(load); 2085 AddInstruction(load);
2172 StoreLocalComp* store_local = new StoreLocalComp( 2086 StoreLocalComp* store_local = new StoreLocalComp(
2173 parameter, 2087 parameter,
2174 new UseVal(load), 2088 new UseVal(load),
2175 owner()->context_level()); 2089 owner()->context_level());
2176 AddInstruction(new DoInstr(store_local)); 2090 AddInstruction(new DoInstr(store_local));
2177 // Write NULL to the source location to detect buggy accesses and 2091 // Write NULL to the source location to detect buggy accesses and
2178 // allow GC of passed value if it gets overwritten by a new value in 2092 // allow GC of passed value if it gets overwritten by a new value in
2179 // the function. 2093 // the function.
2180 BindInstr* null_constant = 2094 BindInstr* null_constant =
2181 new BindInstr(temp_index(), 2095 new BindInstr(new ConstantVal(Object::ZoneHandle()));
2182 new ConstantVal(Object::ZoneHandle()));
2183 AddInstruction(null_constant); 2096 AddInstruction(null_constant);
2184 StoreLocalComp* clear_local = new StoreLocalComp( 2097 StoreLocalComp* clear_local = new StoreLocalComp(
2185 *temp_local, 2098 *temp_local,
2186 new UseVal(null_constant), 2099 new UseVal(null_constant),
2187 owner()->context_level()); 2100 owner()->context_level());
2188 AddInstruction(new DoInstr(clear_local)); 2101 AddInstruction(new DoInstr(clear_local));
2189 } 2102 }
2190 } 2103 }
2191 } 2104 }
2192 } 2105 }
2193 2106
2194 if (FLAG_enable_type_checks && 2107 if (FLAG_enable_type_checks &&
2195 (node == owner()->parsed_function().node_sequence())) { 2108 (node == owner()->parsed_function().node_sequence())) {
2196 const int num_params = 2109 const int num_params =
2197 owner()->parsed_function().function().NumberOfParameters(); 2110 owner()->parsed_function().function().NumberOfParameters();
2198 for (int pos = 0; pos < num_params; pos++) { 2111 for (int pos = 0; pos < num_params; pos++) {
2199 const LocalVariable& parameter = *scope->VariableAt(pos); 2112 const LocalVariable& parameter = *scope->VariableAt(pos);
2200 ASSERT(parameter.owner() == scope); 2113 ASSERT(parameter.owner() == scope);
2201 if (!CanSkipTypeCheck(NULL, parameter.type())) { 2114 if (!CanSkipTypeCheck(NULL, parameter.type())) {
2202 BindInstr* load = 2115 BindInstr* load =
2203 new BindInstr(temp_index(), 2116 new BindInstr(new LoadLocalComp(parameter,
2204 new LoadLocalComp(parameter,
2205 owner()->context_level())); 2117 owner()->context_level()));
2206 AddInstruction(load); 2118 AddInstruction(load);
2207 BuildAssertAssignable(parameter.token_index(), 2119 BuildAssertAssignable(parameter.token_index(),
2208 new UseVal(load), 2120 new UseVal(load),
2209 parameter.type(), 2121 parameter.type(),
2210 parameter.name(), 2122 parameter.name());
2211 temp_index());
2212 } 2123 }
2213 } 2124 }
2214 } 2125 }
2215 2126
2216 intptr_t i = 0; 2127 intptr_t i = 0;
2217 while (is_open() && (i < node->length())) { 2128 while (is_open() && (i < node->length())) {
2218 EffectGraphVisitor for_effect(owner(), temp_index()); 2129 EffectGraphVisitor for_effect(owner(), temp_index());
2219 node->NodeAt(i++)->Visit(&for_effect); 2130 node->NodeAt(i++)->Visit(&for_effect);
2220 Append(for_effect); 2131 Append(for_effect);
2221 if (!is_open()) { 2132 if (!is_open()) {
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
2928 char* chars = reinterpret_cast<char*>( 2839 char* chars = reinterpret_cast<char*>(
2929 Isolate::Current()->current_zone()->Allocate(len)); 2840 Isolate::Current()->current_zone()->Allocate(len));
2930 OS::SNPrint(chars, len, kFormat, function_name, reason); 2841 OS::SNPrint(chars, len, kFormat, function_name, reason);
2931 const Error& error = Error::Handle( 2842 const Error& error = Error::Handle(
2932 LanguageError::New(String::Handle(String::New(chars)))); 2843 LanguageError::New(String::Handle(String::New(chars))));
2933 Isolate::Current()->long_jump_base()->Jump(1, error); 2844 Isolate::Current()->long_jump_base()->Jump(1, error);
2934 } 2845 }
2935 2846
2936 2847
2937 } // namespace dart 2848 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698