OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |