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

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

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_builder_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/bit_vector.h" 9 #include "vm/bit_vector.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 14 matching lines...) Expand all
25 #include "vm/resolver.h" 25 #include "vm/resolver.h"
26 #include "vm/scopes.h" 26 #include "vm/scopes.h"
27 #include "vm/stack_frame.h" 27 #include "vm/stack_frame.h"
28 #include "vm/stub_code.h" 28 #include "vm/stub_code.h"
29 #include "vm/symbols.h" 29 #include "vm/symbols.h"
30 #include "vm/token.h" 30 #include "vm/token.h"
31 #include "vm/zone.h" 31 #include "vm/zone.h"
32 32
33 namespace dart { 33 namespace dart {
34 34
35 DEFINE_FLAG(bool, eliminate_type_checks, true, 35 DEFINE_FLAG(bool,
36 eliminate_type_checks,
37 true,
36 "Eliminate type checks when allowed by static type analysis."); 38 "Eliminate type checks when allowed by static type analysis.");
37 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree."); 39 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree.");
38 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); 40 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables.");
39 DEFINE_FLAG(bool, trace_type_check_elimination, false, 41 DEFINE_FLAG(bool,
42 trace_type_check_elimination,
43 false,
40 "Trace type check elimination at compile time."); 44 "Trace type check elimination at compile time.");
41 45
42 DECLARE_FLAG(bool, profile_vm); 46 DECLARE_FLAG(bool, profile_vm);
43 DECLARE_FLAG(bool, support_externalizable_strings); 47 DECLARE_FLAG(bool, support_externalizable_strings);
44 48
45 // Quick access to the locally defined zone() method. 49 // Quick access to the locally defined zone() method.
46 #define Z (zone()) 50 #define Z (zone())
47 51
48 // Quick access to the locally defined thread() method. 52 // Quick access to the locally defined thread() method.
49 #define T (thread()) 53 #define T (thread())
50 54
51 // Quick synthetic token position. 55 // Quick synthetic token position.
52 #define ST(token_pos) ((token_pos).ToSynthetic()) 56 #define ST(token_pos) ((token_pos).ToSynthetic())
53 57
54 // TODO(srdjan): Allow compiler to add constants as they are encountered in 58 // TODO(srdjan): Allow compiler to add constants as they are encountered in
55 // the compilation. 59 // the compilation.
56 const double kCommonDoubleConstants[] = 60 const double kCommonDoubleConstants[] = {
57 {-1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0, 61 -1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0, 10.0, 20.0, 30.0, 64.0,
58 10.0, 20.0, 30.0, 64.0, 255.0, NAN, 62 255.0, NAN,
59 // From dart:math 63 // From dart:math
60 2.718281828459045, 2.302585092994046, 0.6931471805599453, 64 2.718281828459045, 2.302585092994046, 0.6931471805599453,
61 1.4426950408889634, 0.4342944819032518, 3.1415926535897932, 65 1.4426950408889634, 0.4342944819032518, 3.1415926535897932,
62 0.7071067811865476, 1.4142135623730951}; 66 0.7071067811865476, 1.4142135623730951};
63 67
64 uword FlowGraphBuilder::FindDoubleConstant(double value) { 68 uword FlowGraphBuilder::FindDoubleConstant(double value) {
65 intptr_t len = sizeof(kCommonDoubleConstants) / sizeof(double); // NOLINT 69 intptr_t len = sizeof(kCommonDoubleConstants) / sizeof(double); // NOLINT
66 for (intptr_t i = 0; i < len; i++) { 70 for (intptr_t i = 0; i < len; i++) {
67 if (Utils::DoublesBitEqual(value, kCommonDoubleConstants[i])) { 71 if (Utils::DoublesBitEqual(value, kCommonDoubleConstants[i])) {
68 return reinterpret_cast<uword>(&kCommonDoubleConstants[i]); 72 return reinterpret_cast<uword>(&kCommonDoubleConstants[i]);
69 } 73 }
70 } 74 }
71 return 0; 75 return 0;
72 } 76 }
73 77
74 78
75 #define RECOGNIZE_FACTORY(test_factory_symbol, cid, fp) \ 79 #define RECOGNIZE_FACTORY(test_factory_symbol, cid, fp) \
76 { Symbols::k##test_factory_symbol##Id, cid, \ 80 {Symbols::k##test_factory_symbol##Id, cid, fp, \
77 fp, #test_factory_symbol ", " #cid }, 81 #test_factory_symbol ", " #cid}, // NOLINT
78 82
79 static struct { 83 static struct {
80 intptr_t symbold_id; 84 intptr_t symbold_id;
81 intptr_t cid; 85 intptr_t cid;
82 intptr_t finger_print; 86 intptr_t finger_print;
83 const char* name; 87 const char* name;
84 } factory_recognizer_list[] = { 88 } factory_recognizer_list[] = {RECOGNIZED_LIST_FACTORY_LIST(RECOGNIZE_FACTORY){
85 RECOGNIZED_LIST_FACTORY_LIST(RECOGNIZE_FACTORY) 89 Symbols::kIllegal, -1, -1, NULL}};
86 { Symbols::kIllegal, -1, -1, NULL }
87 };
88 90
89 #undef RECOGNIZE_FACTORY 91 #undef RECOGNIZE_FACTORY
90 92
91 intptr_t FactoryRecognizer::ResultCid(const Function& factory) { 93 intptr_t FactoryRecognizer::ResultCid(const Function& factory) {
92 ASSERT(factory.IsFactory()); 94 ASSERT(factory.IsFactory());
93 const Class& function_class = Class::Handle(factory.Owner()); 95 const Class& function_class = Class::Handle(factory.Owner());
94 const Library& lib = Library::Handle(function_class.library()); 96 const Library& lib = Library::Handle(function_class.library());
95 ASSERT((lib.raw() == Library::CoreLibrary()) || 97 ASSERT((lib.raw() == Library::CoreLibrary()) ||
96 (lib.raw() == Library::TypedDataLibrary())); 98 (lib.raw() == Library::TypedDataLibrary()));
97 const String& factory_name = String::Handle(factory.name()); 99 const String& factory_name = String::Handle(factory.name());
98 for (intptr_t i = 0; 100 for (intptr_t i = 0;
99 factory_recognizer_list[i].symbold_id != Symbols::kIllegal; 101 factory_recognizer_list[i].symbold_id != Symbols::kIllegal; i++) {
100 i++) {
101 if (String::EqualsIgnoringPrivateKey( 102 if (String::EqualsIgnoringPrivateKey(
102 factory_name, 103 factory_name,
103 Symbols::Symbol(factory_recognizer_list[i].symbold_id))) { 104 Symbols::Symbol(factory_recognizer_list[i].symbold_id))) {
104 return factory_recognizer_list[i].cid; 105 return factory_recognizer_list[i].cid;
105 } 106 }
106 } 107 }
107 return kDynamicCid; 108 return kDynamicCid;
108 } 109 }
109 110
110 111
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 167
167 168
168 intptr_t FlowGraphBuilder::context_level() const { 169 intptr_t FlowGraphBuilder::context_level() const {
169 return (nesting_stack() == NULL) ? 0 : nesting_stack()->ContextLevel(); 170 return (nesting_stack() == NULL) ? 0 : nesting_stack()->ContextLevel();
170 } 171 }
171 172
172 173
173 JoinEntryInstr* NestedStatement::BreakTargetFor(SourceLabel* label) { 174 JoinEntryInstr* NestedStatement::BreakTargetFor(SourceLabel* label) {
174 if (label != label_) return NULL; 175 if (label != label_) return NULL;
175 if (break_target_ == NULL) { 176 if (break_target_ == NULL) {
176 break_target_ = 177 break_target_ = new (owner()->zone())
177 new(owner()->zone()) JoinEntryInstr(owner()->AllocateBlockId(), 178 JoinEntryInstr(owner()->AllocateBlockId(), try_index());
178 try_index());
179 } 179 }
180 return break_target_; 180 return break_target_;
181 } 181 }
182 182
183 183
184 JoinEntryInstr* NestedStatement::ContinueTargetFor(SourceLabel* label) { 184 JoinEntryInstr* NestedStatement::ContinueTargetFor(SourceLabel* label) {
185 return NULL; 185 return NULL;
186 } 186 }
187 187
188 188
189 // A nested statement that has its own context level. 189 // A nested statement that has its own context level.
190 class NestedBlock : public NestedStatement { 190 class NestedBlock : public NestedStatement {
191 public: 191 public:
192 NestedBlock(FlowGraphBuilder* owner, SequenceNode* node) 192 NestedBlock(FlowGraphBuilder* owner, SequenceNode* node)
193 : NestedStatement(owner, node->label()), scope_(node->scope()) {} 193 : NestedStatement(owner, node->label()), scope_(node->scope()) {}
194 194
195 virtual intptr_t ContextLevel() const; 195 virtual intptr_t ContextLevel() const;
196 196
197 private: 197 private:
198 LocalScope* scope_; 198 LocalScope* scope_;
199 }; 199 };
200 200
201 201
202 intptr_t NestedBlock::ContextLevel() const { 202 intptr_t NestedBlock::ContextLevel() const {
203 return ((scope_ == NULL) || (scope_->num_context_variables() == 0)) 203 return ((scope_ == NULL) || (scope_->num_context_variables() == 0))
204 ? NestedStatement::ContextLevel() 204 ? NestedStatement::ContextLevel()
205 : scope_->context_level(); 205 : scope_->context_level();
206 } 206 }
207 207
208 208
209 // A nested statement reflecting a context level adjustment. 209 // A nested statement reflecting a context level adjustment.
210 class NestedContextAdjustment : public NestedStatement { 210 class NestedContextAdjustment : public NestedStatement {
211 public: 211 public:
212 NestedContextAdjustment(FlowGraphBuilder* owner, intptr_t context_level) 212 NestedContextAdjustment(FlowGraphBuilder* owner, intptr_t context_level)
213 : NestedStatement(owner, NULL), context_level_(context_level) { } 213 : NestedStatement(owner, NULL), context_level_(context_level) {}
214 214
215 virtual intptr_t ContextLevel() const { return context_level_; } 215 virtual intptr_t ContextLevel() const { return context_level_; }
216 216
217 virtual void AdjustContextLevel(intptr_t context_level) { 217 virtual void AdjustContextLevel(intptr_t context_level) {
218 ASSERT(context_level <= context_level_); 218 ASSERT(context_level <= context_level_);
219 context_level_ = context_level; 219 context_level_ = context_level;
220 } 220 }
221 221
222 private: 222 private:
223 intptr_t context_level_; 223 intptr_t context_level_;
224 }; 224 };
225 225
226 226
227 // A nested statement that can be the target of a continue as well as a 227 // A nested statement that can be the target of a continue as well as a
228 // break. 228 // break.
229 class NestedLoop : public NestedStatement { 229 class NestedLoop : public NestedStatement {
230 public: 230 public:
231 NestedLoop(FlowGraphBuilder* owner, SourceLabel* label) 231 NestedLoop(FlowGraphBuilder* owner, SourceLabel* label)
232 : NestedStatement(owner, label), continue_target_(NULL) { 232 : NestedStatement(owner, label), continue_target_(NULL) {
233 owner->IncrementLoopDepth(); 233 owner->IncrementLoopDepth();
234 } 234 }
235 235
236 virtual ~NestedLoop() { 236 virtual ~NestedLoop() { owner()->DecrementLoopDepth(); }
237 owner()->DecrementLoopDepth();
238 }
239 237
240 JoinEntryInstr* continue_target() const { return continue_target_; } 238 JoinEntryInstr* continue_target() const { return continue_target_; }
241 239
242 virtual JoinEntryInstr* ContinueTargetFor(SourceLabel* label); 240 virtual JoinEntryInstr* ContinueTargetFor(SourceLabel* label);
243 241
244 private: 242 private:
245 JoinEntryInstr* continue_target_; 243 JoinEntryInstr* continue_target_;
246 }; 244 };
247 245
248 246
249 JoinEntryInstr* NestedLoop::ContinueTargetFor(SourceLabel* label) { 247 JoinEntryInstr* NestedLoop::ContinueTargetFor(SourceLabel* label) {
250 if (label != this->label()) return NULL; 248 if (label != this->label()) return NULL;
251 if (continue_target_ == NULL) { 249 if (continue_target_ == NULL) {
252 continue_target_ = 250 continue_target_ = new (owner()->zone())
253 new(owner()->zone()) JoinEntryInstr(owner()->AllocateBlockId(), 251 JoinEntryInstr(owner()->AllocateBlockId(), try_index());
254 try_index());
255 } 252 }
256 return continue_target_; 253 return continue_target_;
257 } 254 }
258 255
259 256
260 // A nested switch which can be the target of a break if labeled, and whose 257 // A nested switch which can be the target of a break if labeled, and whose
261 // cases can be the targets of continues. 258 // cases can be the targets of continues.
262 class NestedSwitch : public NestedStatement { 259 class NestedSwitch : public NestedStatement {
263 public: 260 public:
264 NestedSwitch(FlowGraphBuilder* owner, SwitchNode* node); 261 NestedSwitch(FlowGraphBuilder* owner, SwitchNode* node);
(...skipping 21 matching lines...) Expand all
286 } 283 }
287 284
288 285
289 JoinEntryInstr* NestedSwitch::ContinueTargetFor(SourceLabel* label) { 286 JoinEntryInstr* NestedSwitch::ContinueTargetFor(SourceLabel* label) {
290 // Allocate a join for a case clause that matches the label. This block 287 // Allocate a join for a case clause that matches the label. This block
291 // is not necessarily targeted by a continue, but we always use a join in 288 // is not necessarily targeted by a continue, but we always use a join in
292 // the graph anyway. 289 // the graph anyway.
293 for (intptr_t i = 0; i < case_labels_.length(); ++i) { 290 for (intptr_t i = 0; i < case_labels_.length(); ++i) {
294 if (label != case_labels_[i]) continue; 291 if (label != case_labels_[i]) continue;
295 if (case_targets_[i] == NULL) { 292 if (case_targets_[i] == NULL) {
296 case_targets_[i] = 293 case_targets_[i] = new (owner()->zone())
297 new(owner()->zone()) JoinEntryInstr(owner()->AllocateBlockId(), 294 JoinEntryInstr(owner()->AllocateBlockId(), try_index());
298 try_index());
299 } 295 }
300 return case_targets_[i]; 296 return case_targets_[i];
301 } 297 }
302 return NULL; 298 return NULL;
303 } 299 }
304 300
305 301
306 FlowGraphBuilder::FlowGraphBuilder( 302 FlowGraphBuilder::FlowGraphBuilder(
307 const ParsedFunction& parsed_function, 303 const ParsedFunction& parsed_function,
308 const ZoneGrowableArray<const ICData*>& ic_data_array, 304 const ZoneGrowableArray<const ICData*>& ic_data_array,
309 InlineExitCollector* exit_collector, 305 InlineExitCollector* exit_collector,
310 intptr_t osr_id) : 306 intptr_t osr_id)
311 parsed_function_(parsed_function), 307 : parsed_function_(parsed_function),
312 ic_data_array_(ic_data_array), 308 ic_data_array_(ic_data_array),
313 num_copied_params_(parsed_function.num_copied_params()), 309 num_copied_params_(parsed_function.num_copied_params()),
314 // All parameters are copied if any parameter is. 310 // All parameters are copied if any parameter is.
315 num_non_copied_params_((num_copied_params_ == 0) 311 num_non_copied_params_(
316 ? parsed_function.function().num_fixed_parameters() 312 (num_copied_params_ == 0)
317 : 0), 313 ? parsed_function.function().num_fixed_parameters()
318 num_stack_locals_(parsed_function.num_stack_locals()), 314 : 0),
319 exit_collector_(exit_collector), 315 num_stack_locals_(parsed_function.num_stack_locals()),
320 last_used_block_id_(0), // 0 is used for the graph entry. 316 exit_collector_(exit_collector),
321 try_index_(CatchClauseNode::kInvalidTryIndex), 317 last_used_block_id_(0), // 0 is used for the graph entry.
322 catch_try_index_(CatchClauseNode::kInvalidTryIndex), 318 try_index_(CatchClauseNode::kInvalidTryIndex),
323 loop_depth_(0), 319 catch_try_index_(CatchClauseNode::kInvalidTryIndex),
324 graph_entry_(NULL), 320 loop_depth_(0),
325 temp_count_(0), 321 graph_entry_(NULL),
326 args_pushed_(0), 322 temp_count_(0),
327 nesting_stack_(NULL), 323 args_pushed_(0),
328 osr_id_(osr_id), 324 nesting_stack_(NULL),
329 jump_count_(0), 325 osr_id_(osr_id),
330 await_joins_(new(Z) ZoneGrowableArray<JoinEntryInstr*>()) { } 326 jump_count_(0),
327 await_joins_(new (Z) ZoneGrowableArray<JoinEntryInstr*>()) {}
331 328
332 329
333 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) { 330 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) {
334 graph_entry_->AddCatchEntry(entry); 331 graph_entry_->AddCatchEntry(entry);
335 } 332 }
336 333
337 334
338 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) { 335 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) {
339 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1); 336 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1);
340 ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id()); 337 ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id());
341 ASSERT(callee_graph->max_virtual_register_number() > 338 ASSERT(callee_graph->max_virtual_register_number() >
342 caller_graph_->max_virtual_register_number()); 339 caller_graph_->max_virtual_register_number());
343 340
344 // Adjust the caller's maximum block id and current SSA temp index. 341 // Adjust the caller's maximum block id and current SSA temp index.
345 caller_graph_->set_max_block_id(callee_graph->max_block_id()); 342 caller_graph_->set_max_block_id(callee_graph->max_block_id());
346 caller_graph_->set_current_ssa_temp_index( 343 caller_graph_->set_current_ssa_temp_index(
347 callee_graph->max_virtual_register_number()); 344 callee_graph->max_virtual_register_number());
348 345
349 // Attach the outer environment on each instruction in the callee graph. 346 // Attach the outer environment on each instruction in the callee graph.
350 ASSERT(call_->env() != NULL); 347 ASSERT(call_->env() != NULL);
351 // Scale the edge weights by the call count for the inlined function. 348 // Scale the edge weights by the call count for the inlined function.
352 double scale_factor = static_cast<double>(call_->CallCount()) 349 double scale_factor =
353 / static_cast<double>(caller_graph_->graph_entry()->entry_count()); 350 static_cast<double>(call_->CallCount()) /
351 static_cast<double>(caller_graph_->graph_entry()->entry_count());
354 for (BlockIterator block_it = callee_graph->postorder_iterator(); 352 for (BlockIterator block_it = callee_graph->postorder_iterator();
355 !block_it.Done(); 353 !block_it.Done(); block_it.Advance()) {
356 block_it.Advance()) {
357 BlockEntryInstr* block = block_it.Current(); 354 BlockEntryInstr* block = block_it.Current();
358 if (block->IsTargetEntry()) { 355 if (block->IsTargetEntry()) {
359 block->AsTargetEntry()->adjust_edge_weight(scale_factor); 356 block->AsTargetEntry()->adjust_edge_weight(scale_factor);
360 } 357 }
361 Instruction* instr = block; 358 Instruction* instr = block;
362 if (block->env() != NULL) { 359 if (block->env() != NULL) {
363 call_->env()->DeepCopyToOuter(callee_graph->zone(), block); 360 call_->env()->DeepCopyToOuter(callee_graph->zone(), block);
364 } 361 }
365 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 362 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
366 instr = it.Current(); 363 instr = it.Current();
367 // TODO(zerny): Avoid creating unnecessary environments. Note that some 364 // TODO(zerny): Avoid creating unnecessary environments. Note that some
368 // optimizations need deoptimization info for non-deoptable instructions, 365 // optimizations need deoptimization info for non-deoptable instructions,
369 // eg, LICM on GOTOs. 366 // eg, LICM on GOTOs.
370 if (instr->env() != NULL) { 367 if (instr->env() != NULL) {
371 call_->env()->DeepCopyToOuter(callee_graph->zone(), instr); 368 call_->env()->DeepCopyToOuter(callee_graph->zone(), instr);
372 } 369 }
373 } 370 }
374 if (instr->IsGoto()) { 371 if (instr->IsGoto()) {
375 instr->AsGoto()->adjust_edge_weight(scale_factor); 372 instr->AsGoto()->adjust_edge_weight(scale_factor);
376 } 373 }
377 } 374 }
378 375
379 RemoveUnreachableExits(callee_graph); 376 RemoveUnreachableExits(callee_graph);
380 } 377 }
381 378
382 379
383 void InlineExitCollector::AddExit(ReturnInstr* exit) { 380 void InlineExitCollector::AddExit(ReturnInstr* exit) {
384 Data data = { NULL, exit }; 381 Data data = {NULL, exit};
385 exits_.Add(data); 382 exits_.Add(data);
386 } 383 }
387 384
388 385
389 void InlineExitCollector::Union(const InlineExitCollector* other) { 386 void InlineExitCollector::Union(const InlineExitCollector* other) {
390 // It doesn't make sense to combine different calls or calls from 387 // It doesn't make sense to combine different calls or calls from
391 // different graphs. 388 // different graphs.
392 ASSERT(caller_graph_ == other->caller_graph_); 389 ASSERT(caller_graph_ == other->caller_graph_);
393 ASSERT(call_ == other->call_); 390 ASSERT(call_ == other->call_);
394 exits_.AddArray(other->exits_); 391 exits_.AddArray(other->exits_);
395 } 392 }
396 393
397 394
398 int InlineExitCollector::LowestBlockIdFirst(const Data* a, const Data* b) { 395 int InlineExitCollector::LowestBlockIdFirst(const Data* a, const Data* b) {
399 return (a->exit_block->block_id() - b->exit_block->block_id()); 396 return (a->exit_block->block_id() - b->exit_block->block_id());
400 } 397 }
401 398
402 399
403 void InlineExitCollector::RemoveUnreachableExits(FlowGraph* callee_graph) { 400 void InlineExitCollector::RemoveUnreachableExits(FlowGraph* callee_graph) {
404 const GrowableArray<BlockEntryInstr*>& postorder = callee_graph->postorder(); 401 const GrowableArray<BlockEntryInstr*>& postorder = callee_graph->postorder();
405 int j = 0; 402 int j = 0;
406 for (int i = 0; i < exits_.length(); ++i) { 403 for (int i = 0; i < exits_.length(); ++i) {
407 BlockEntryInstr* block = exits_[i].exit_return->GetBlock(); 404 BlockEntryInstr* block = exits_[i].exit_return->GetBlock();
408 if ((block != NULL) && 405 if ((block != NULL) && (0 <= block->postorder_number()) &&
409 (0 <= block->postorder_number()) &&
410 (block->postorder_number() < postorder.length()) && 406 (block->postorder_number() < postorder.length()) &&
411 (postorder[block->postorder_number()] == block)) { 407 (postorder[block->postorder_number()] == block)) {
412 if (i != j) { 408 if (i != j) {
413 exits_[j] = exits_[i]; 409 exits_[j] = exits_[i];
414 } 410 }
415 j++; 411 j++;
416 } 412 }
417 } 413 }
418 exits_.TruncateTo(j); 414 exits_.TruncateTo(j);
419 } 415 }
(...skipping 19 matching lines...) Expand all
439 if (num_exits == 1) { 435 if (num_exits == 1) {
440 ReturnAt(0)->UnuseAllInputs(); 436 ReturnAt(0)->UnuseAllInputs();
441 *exit_block = ExitBlockAt(0); 437 *exit_block = ExitBlockAt(0);
442 *last_instruction = LastInstructionAt(0); 438 *last_instruction = LastInstructionAt(0);
443 return call_->HasUses() ? ValueAt(0)->definition() : NULL; 439 return call_->HasUses() ? ValueAt(0)->definition() : NULL;
444 } else { 440 } else {
445 ASSERT(num_exits > 1); 441 ASSERT(num_exits > 1);
446 // Create a join of the returns. 442 // Create a join of the returns.
447 intptr_t join_id = caller_graph_->max_block_id() + 1; 443 intptr_t join_id = caller_graph_->max_block_id() + 1;
448 caller_graph_->set_max_block_id(join_id); 444 caller_graph_->set_max_block_id(join_id);
449 JoinEntryInstr* join = 445 JoinEntryInstr* join = new (Z) JoinEntryInstr(join_id, try_index);
450 new(Z) JoinEntryInstr(join_id, try_index);
451 446
452 // The dominator set of the join is the intersection of the dominator 447 // The dominator set of the join is the intersection of the dominator
453 // sets of all the predecessors. If we keep the dominator sets ordered 448 // sets of all the predecessors. If we keep the dominator sets ordered
454 // by height in the dominator tree, we can also get the immediate 449 // by height in the dominator tree, we can also get the immediate
455 // dominator of the join node from the intersection. 450 // dominator of the join node from the intersection.
456 // 451 //
457 // block_dominators is the dominator set for each block, ordered from 452 // block_dominators is the dominator set for each block, ordered from
458 // the immediate dominator to the root of the dominator tree. This is 453 // the immediate dominator to the root of the dominator tree. This is
459 // the order we collect them in (adding at the end). 454 // the order we collect them in (adding at the end).
460 // 455 //
461 // join_dominators is the join's dominators ordered from the root of the 456 // join_dominators is the join's dominators ordered from the root of the
462 // dominator tree to the immediate dominator. This order supports 457 // dominator tree to the immediate dominator. This order supports
463 // removing during intersection by truncating the list. 458 // removing during intersection by truncating the list.
464 GrowableArray<BlockEntryInstr*> block_dominators; 459 GrowableArray<BlockEntryInstr*> block_dominators;
465 GrowableArray<BlockEntryInstr*> join_dominators; 460 GrowableArray<BlockEntryInstr*> join_dominators;
466 for (intptr_t i = 0; i < num_exits; ++i) { 461 for (intptr_t i = 0; i < num_exits; ++i) {
467 // Add the control-flow edge. 462 // Add the control-flow edge.
468 GotoInstr* goto_instr = new(Z) GotoInstr(join); 463 GotoInstr* goto_instr = new (Z) GotoInstr(join);
469 goto_instr->InheritDeoptTarget(zone(), ReturnAt(i)); 464 goto_instr->InheritDeoptTarget(zone(), ReturnAt(i));
470 LastInstructionAt(i)->LinkTo(goto_instr); 465 LastInstructionAt(i)->LinkTo(goto_instr);
471 ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next()); 466 ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next());
472 join->predecessors_.Add(ExitBlockAt(i)); 467 join->predecessors_.Add(ExitBlockAt(i));
473 468
474 // Collect the block's dominators. 469 // Collect the block's dominators.
475 block_dominators.Clear(); 470 block_dominators.Clear();
476 BlockEntryInstr* dominator = ExitBlockAt(i)->dominator(); 471 BlockEntryInstr* dominator = ExitBlockAt(i)->dominator();
477 while (dominator != NULL) { 472 while (dominator != NULL) {
478 block_dominators.Add(dominator); 473 block_dominators.Add(dominator);
(...skipping 25 matching lines...) Expand all
504 } 499 }
505 // The immediate dominator of the join is the last one in the ordered 500 // The immediate dominator of the join is the last one in the ordered
506 // intersection. 501 // intersection.
507 join_dominators.Last()->AddDominatedBlock(join); 502 join_dominators.Last()->AddDominatedBlock(join);
508 *exit_block = join; 503 *exit_block = join;
509 *last_instruction = join; 504 *last_instruction = join;
510 505
511 // If the call has uses, create a phi of the returns. 506 // If the call has uses, create a phi of the returns.
512 if (call_->HasUses()) { 507 if (call_->HasUses()) {
513 // Add a phi of the return values. 508 // Add a phi of the return values.
514 PhiInstr* phi = new(Z) PhiInstr(join, num_exits); 509 PhiInstr* phi = new (Z) PhiInstr(join, num_exits);
515 caller_graph_->AllocateSSAIndexes(phi); 510 caller_graph_->AllocateSSAIndexes(phi);
516 phi->mark_alive(); 511 phi->mark_alive();
517 for (intptr_t i = 0; i < num_exits; ++i) { 512 for (intptr_t i = 0; i < num_exits; ++i) {
518 ReturnAt(i)->RemoveEnvironment(); 513 ReturnAt(i)->RemoveEnvironment();
519 phi->SetInputAt(i, ValueAt(i)); 514 phi->SetInputAt(i, ValueAt(i));
520 } 515 }
521 join->InsertPhi(phi); 516 join->InsertPhi(phi);
522 join->InheritDeoptTargetAfter(caller_graph_, call_, phi); 517 join->InheritDeoptTargetAfter(caller_graph_, call_, phi);
523 return phi; 518 return phi;
524 } else { 519 } else {
(...skipping 18 matching lines...) Expand all
543 BlockEntryInstr* callee_exit = NULL; 538 BlockEntryInstr* callee_exit = NULL;
544 Instruction* callee_last_instruction = NULL; 539 Instruction* callee_last_instruction = NULL;
545 540
546 if (exits_.length() == 0) { 541 if (exits_.length() == 0) {
547 // Handle the case when there are no normal return exits from the callee 542 // Handle the case when there are no normal return exits from the callee
548 // (i.e. the callee unconditionally throws) by inserting an artificial 543 // (i.e. the callee unconditionally throws) by inserting an artificial
549 // branch (true === true). 544 // branch (true === true).
550 // The true successor is the inlined body, the false successor 545 // The true successor is the inlined body, the false successor
551 // goes to the rest of the caller graph. It is removed as unreachable code 546 // goes to the rest of the caller graph. It is removed as unreachable code
552 // by the constant propagation. 547 // by the constant propagation.
553 TargetEntryInstr* false_block = 548 TargetEntryInstr* false_block = new (Z) TargetEntryInstr(
554 new(Z) TargetEntryInstr(caller_graph_->allocate_block_id(), 549 caller_graph_->allocate_block_id(), call_block->try_index());
555 call_block->try_index());
556 false_block->InheritDeoptTargetAfter(caller_graph_, call_, NULL); 550 false_block->InheritDeoptTargetAfter(caller_graph_, call_, NULL);
557 false_block->LinkTo(call_->next()); 551 false_block->LinkTo(call_->next());
558 call_block->ReplaceAsPredecessorWith(false_block); 552 call_block->ReplaceAsPredecessorWith(false_block);
559 553
560 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True()); 554 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True());
561 BranchInstr* branch = 555 BranchInstr* branch = new (Z) BranchInstr(new (Z) StrictCompareInstr(
562 new(Z) BranchInstr( 556 TokenPosition::kNoSource, Token::kEQ_STRICT, new (Z) Value(true_const),
563 new(Z) StrictCompareInstr(TokenPosition::kNoSource, 557 new (Z) Value(true_const),
564 Token::kEQ_STRICT, 558 false)); // No number check.
565 new(Z) Value(true_const),
566 new(Z) Value(true_const),
567 false)); // No number check.
568 branch->InheritDeoptTarget(zone(), call_); 559 branch->InheritDeoptTarget(zone(), call_);
569 *branch->true_successor_address() = callee_entry; 560 *branch->true_successor_address() = callee_entry;
570 *branch->false_successor_address() = false_block; 561 *branch->false_successor_address() = false_block;
571 562
572 call_->previous()->AppendInstruction(branch); 563 call_->previous()->AppendInstruction(branch);
573 call_block->set_last_instruction(branch); 564 call_block->set_last_instruction(branch);
574 565
575 // Replace uses of the return value with null to maintain valid 566 // Replace uses of the return value with null to maintain valid
576 // SSA form - even though the rest of the caller is unreachable. 567 // SSA form - even though the rest of the caller is unreachable.
577 call_->ReplaceUsesWith(caller_graph_->constant_null()); 568 call_->ReplaceUsesWith(caller_graph_->constant_null());
578 569
579 // Update dominator tree. 570 // Update dominator tree.
580 call_block->AddDominatedBlock(callee_entry); 571 call_block->AddDominatedBlock(callee_entry);
581 call_block->AddDominatedBlock(false_block); 572 call_block->AddDominatedBlock(false_block);
582 573
583 } else { 574 } else {
584 Definition* callee_result = JoinReturns(&callee_exit, 575 Definition* callee_result = JoinReturns(
585 &callee_last_instruction, 576 &callee_exit, &callee_last_instruction, call_block->try_index());
586 call_block->try_index());
587 if (callee_result != NULL) { 577 if (callee_result != NULL) {
588 call_->ReplaceUsesWith(callee_result); 578 call_->ReplaceUsesWith(callee_result);
589 } 579 }
590 if (callee_last_instruction == callee_entry) { 580 if (callee_last_instruction == callee_entry) {
591 // There are no instructions in the inlined function (e.g., it might be 581 // There are no instructions in the inlined function (e.g., it might be
592 // a return of a parameter or a return of a constant defined in the 582 // a return of a parameter or a return of a constant defined in the
593 // initial definitions). 583 // initial definitions).
594 call_->previous()->LinkTo(call_->next()); 584 call_->previous()->LinkTo(call_->next());
595 } else { 585 } else {
596 call_->previous()->LinkTo(callee_entry->next()); 586 call_->previous()->LinkTo(callee_entry->next());
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 ASSERT(is_open()); 658 ASSERT(is_open());
669 owner()->DeallocateTemps(definition->InputCount()); 659 owner()->DeallocateTemps(definition->InputCount());
670 owner()->add_args_pushed(-definition->ArgumentCount()); 660 owner()->add_args_pushed(-definition->ArgumentCount());
671 definition->set_temp_index(owner()->AllocateTemp()); 661 definition->set_temp_index(owner()->AllocateTemp());
672 if (is_empty()) { 662 if (is_empty()) {
673 entry_ = definition; 663 entry_ = definition;
674 } else { 664 } else {
675 exit()->LinkTo(definition); 665 exit()->LinkTo(definition);
676 } 666 }
677 exit_ = definition; 667 exit_ = definition;
678 return new(Z) Value(definition); 668 return new (Z) Value(definition);
679 } 669 }
680 670
681 671
682 void EffectGraphVisitor::Do(Definition* definition) { 672 void EffectGraphVisitor::Do(Definition* definition) {
683 ASSERT(is_open()); 673 ASSERT(is_open());
684 owner()->DeallocateTemps(definition->InputCount()); 674 owner()->DeallocateTemps(definition->InputCount());
685 owner()->add_args_pushed(-definition->ArgumentCount()); 675 owner()->add_args_pushed(-definition->ArgumentCount());
686 if (is_empty()) { 676 if (is_empty()) {
687 entry_ = definition; 677 entry_ = definition;
688 } else { 678 } else {
(...skipping 11 matching lines...) Expand all
700 owner()->add_args_pushed(-instruction->ArgumentCount()); 690 owner()->add_args_pushed(-instruction->ArgumentCount());
701 if (is_empty()) { 691 if (is_empty()) {
702 entry_ = exit_ = instruction; 692 entry_ = exit_ = instruction;
703 } else { 693 } else {
704 exit()->LinkTo(instruction); 694 exit()->LinkTo(instruction);
705 exit_ = instruction; 695 exit_ = instruction;
706 } 696 }
707 } 697 }
708 698
709 699
710 void EffectGraphVisitor::AddReturnExit(TokenPosition token_pos, 700 void EffectGraphVisitor::AddReturnExit(TokenPosition token_pos, Value* value) {
711 Value* value) {
712 ASSERT(is_open()); 701 ASSERT(is_open());
713 ReturnInstr* return_instr = new(Z) ReturnInstr(token_pos, value); 702 ReturnInstr* return_instr = new (Z) ReturnInstr(token_pos, value);
714 AddInstruction(return_instr); 703 AddInstruction(return_instr);
715 InlineExitCollector* exit_collector = owner()->exit_collector(); 704 InlineExitCollector* exit_collector = owner()->exit_collector();
716 if (exit_collector != NULL) { 705 if (exit_collector != NULL) {
717 exit_collector->AddExit(return_instr); 706 exit_collector->AddExit(return_instr);
718 } 707 }
719 CloseFragment(); 708 CloseFragment();
720 } 709 }
721 710
722 711
723 void EffectGraphVisitor::Goto(JoinEntryInstr* join) { 712 void EffectGraphVisitor::Goto(JoinEntryInstr* join) {
724 ASSERT(is_open()); 713 ASSERT(is_open());
725 if (is_empty()) { 714 if (is_empty()) {
726 entry_ = new(Z) GotoInstr(join); 715 entry_ = new (Z) GotoInstr(join);
727 } else { 716 } else {
728 exit()->Goto(join); 717 exit()->Goto(join);
729 } 718 }
730 CloseFragment(); 719 CloseFragment();
731 } 720 }
732 721
733 722
734 // Appends a graph fragment to a block entry instruction. Returns the entry 723 // Appends a graph fragment to a block entry instruction. Returns the entry
735 // instruction if the fragment was empty or else the exit of the fragment if 724 // instruction if the fragment was empty or else the exit of the fragment if
736 // it was non-empty (so NULL if the fragment is closed). 725 // it was non-empty (so NULL if the fragment is closed).
(...skipping 28 matching lines...) Expand all
765 754
766 BlockEntryInstr* false_entry = test_fragment.CreateFalseSuccessor(); 755 BlockEntryInstr* false_entry = test_fragment.CreateFalseSuccessor();
767 Instruction* false_exit = AppendFragment(false_entry, false_fragment); 756 Instruction* false_exit = AppendFragment(false_entry, false_fragment);
768 757
769 // 3. Add a join or select one (or neither) of the arms as exit. 758 // 3. Add a join or select one (or neither) of the arms as exit.
770 if (true_exit == NULL) { 759 if (true_exit == NULL) {
771 exit_ = false_exit; // May be NULL. 760 exit_ = false_exit; // May be NULL.
772 } else if (false_exit == NULL) { 761 } else if (false_exit == NULL) {
773 exit_ = true_exit; 762 exit_ = true_exit;
774 } else { 763 } else {
775 JoinEntryInstr* join = 764 JoinEntryInstr* join = new (Z)
776 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 765 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
777 true_exit->Goto(join); 766 true_exit->Goto(join);
778 false_exit->Goto(join); 767 false_exit->Goto(join);
779 exit_ = join; 768 exit_ = join;
780 } 769 }
781 } 770 }
782 771
783 772
784 void EffectGraphVisitor::TieLoop( 773 void EffectGraphVisitor::TieLoop(
785 TokenPosition token_pos, 774 TokenPosition token_pos,
786 const TestGraphVisitor& test_fragment, 775 const TestGraphVisitor& test_fragment,
787 const EffectGraphVisitor& body_fragment, 776 const EffectGraphVisitor& body_fragment,
788 const EffectGraphVisitor& test_preamble_fragment) { 777 const EffectGraphVisitor& test_preamble_fragment) {
789 // We have: a test graph fragment with zero, one, or two available exits; 778 // We have: a test graph fragment with zero, one, or two available exits;
790 // and an effect graph fragment with zero or one available exits. We want 779 // and an effect graph fragment with zero or one available exits. We want
791 // to append the 'while loop' consisting of the test graph fragment as 780 // to append the 'while loop' consisting of the test graph fragment as
792 // condition and the effect graph fragment as body. 781 // condition and the effect graph fragment as body.
793 ASSERT(is_open()); 782 ASSERT(is_open());
794 783
795 // 1. Connect the body to the test if it is reachable, and if so record 784 // 1. Connect the body to the test if it is reachable, and if so record
796 // its exit (if any). 785 // its exit (if any).
797 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor(); 786 BlockEntryInstr* body_entry = test_fragment.CreateTrueSuccessor();
798 Instruction* body_exit = AppendFragment(body_entry, body_fragment); 787 Instruction* body_exit = AppendFragment(body_entry, body_fragment);
799 788
800 // 2. Connect the test to this graph, including the body if reachable and 789 // 2. Connect the test to this graph, including the body if reachable and
801 // using a fresh join node if the body is reachable and has an open exit. 790 // using a fresh join node if the body is reachable and has an open exit.
802 if (body_exit == NULL) { 791 if (body_exit == NULL) {
803 Append(test_preamble_fragment); 792 Append(test_preamble_fragment);
804 Append(test_fragment); 793 Append(test_fragment);
805 } else { 794 } else {
806 JoinEntryInstr* join = 795 JoinEntryInstr* join = new (Z)
807 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 796 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
808 CheckStackOverflowInstr* check = 797 CheckStackOverflowInstr* check =
809 new(Z) CheckStackOverflowInstr(token_pos, owner()->loop_depth()); 798 new (Z) CheckStackOverflowInstr(token_pos, owner()->loop_depth());
810 join->LinkTo(check); 799 join->LinkTo(check);
811 if (!test_preamble_fragment.is_empty()) { 800 if (!test_preamble_fragment.is_empty()) {
812 check->LinkTo(test_preamble_fragment.entry()); 801 check->LinkTo(test_preamble_fragment.entry());
813 test_preamble_fragment.exit()->LinkTo(test_fragment.entry()); 802 test_preamble_fragment.exit()->LinkTo(test_fragment.entry());
814 } else { 803 } else {
815 check->LinkTo(test_fragment.entry()); 804 check->LinkTo(test_fragment.entry());
816 } 805 }
817 Goto(join); 806 Goto(join);
818 body_exit->Goto(join); 807 body_exit->Goto(join);
819 } 808 }
820 809
821 // 3. Set the exit to the graph to be the false successor of the test, a 810 // 3. Set the exit to the graph to be the false successor of the test, a
822 // fresh target node 811 // fresh target node
823 exit_ = test_fragment.CreateFalseSuccessor(); 812 exit_ = test_fragment.CreateFalseSuccessor();
824 } 813 }
825 814
826 815
827 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { 816 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) {
828 owner_->add_args_pushed(1); 817 owner_->add_args_pushed(1);
829 PushArgumentInstr* result = new(Z) PushArgumentInstr(value); 818 PushArgumentInstr* result = new (Z) PushArgumentInstr(value);
830 AddInstruction(result); 819 AddInstruction(result);
831 return result; 820 return result;
832 } 821 }
833 822
834 823
835 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local, 824 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local,
836 Value* value, 825 Value* value,
837 TokenPosition token_pos) { 826 TokenPosition token_pos) {
838 ASSERT(!local.is_captured()); 827 ASSERT(!local.is_captured());
839 ASSERT(!token_pos.IsClassifying()); 828 ASSERT(!token_pos.IsClassifying());
840 return new(Z) StoreLocalInstr(local, value, ST(token_pos)); 829 return new (Z) StoreLocalInstr(local, value, ST(token_pos));
841 } 830 }
842 831
843 832
844 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value, 833 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value,
845 TokenPosition token_pos) { 834 TokenPosition token_pos) {
846 return BuildStoreTemp(*owner()->parsed_function().expression_temp_var(), 835 return BuildStoreTemp(*owner()->parsed_function().expression_temp_var(),
847 value, 836 value, token_pos);
848 token_pos);
849 } 837 }
850 838
851 839
852 Definition* EffectGraphVisitor::BuildLoadExprTemp(TokenPosition token_pos) { 840 Definition* EffectGraphVisitor::BuildLoadExprTemp(TokenPosition token_pos) {
853 ASSERT(!token_pos.IsClassifying()); 841 ASSERT(!token_pos.IsClassifying());
854 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var(), 842 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var(),
855 token_pos); 843 token_pos);
856 } 844 }
857 845
858 846
859 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, 847 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local,
860 Value* value, 848 Value* value,
861 TokenPosition token_pos) { 849 TokenPosition token_pos) {
862 if (local.is_captured()) { 850 if (local.is_captured()) {
863 LocalVariable* tmp_var = EnterTempLocalScope(value); 851 LocalVariable* tmp_var = EnterTempLocalScope(value);
864 intptr_t delta = 852 intptr_t delta = owner()->context_level() - local.owner()->context_level();
865 owner()->context_level() - local.owner()->context_level();
866 ASSERT(delta >= 0); 853 ASSERT(delta >= 0);
867 Value* context = Bind(BuildCurrentContext(token_pos)); 854 Value* context = Bind(BuildCurrentContext(token_pos));
868 while (delta-- > 0) { 855 while (delta-- > 0) {
869 context = Bind(new(Z) LoadFieldInstr( 856 context = Bind(new (Z) LoadFieldInstr(context, Context::parent_offset(),
870 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()), 857 Type::ZoneHandle(Z, Type::null()),
871 token_pos)); 858 token_pos));
872 } 859 }
873 Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var, token_pos)); 860 Value* tmp_val = Bind(new (Z) LoadLocalInstr(*tmp_var, token_pos));
874 StoreInstanceFieldInstr* store = 861 StoreInstanceFieldInstr* store = new (Z)
875 new(Z) StoreInstanceFieldInstr(Context::variable_offset(local.index()), 862 StoreInstanceFieldInstr(Context::variable_offset(local.index()),
876 context, 863 context, tmp_val, kEmitStoreBarrier, token_pos);
877 tmp_val,
878 kEmitStoreBarrier,
879 token_pos);
880 Do(store); 864 Do(store);
881 return ExitTempLocalScope(value); 865 return ExitTempLocalScope(value);
882 } else { 866 } else {
883 return new(Z) StoreLocalInstr(local, value, token_pos); 867 return new (Z) StoreLocalInstr(local, value, token_pos);
884 } 868 }
885 } 869 }
886 870
887 871
888 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local, 872 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local,
889 TokenPosition token_pos) { 873 TokenPosition token_pos) {
890 if (local.IsConst()) { 874 if (local.IsConst()) {
891 return new(Z) ConstantInstr(*local.ConstValue(), token_pos); 875 return new (Z) ConstantInstr(*local.ConstValue(), token_pos);
892 } else if (local.is_captured()) { 876 } else if (local.is_captured()) {
893 intptr_t delta = 877 intptr_t delta = owner()->context_level() - local.owner()->context_level();
894 owner()->context_level() - local.owner()->context_level();
895 ASSERT(delta >= 0); 878 ASSERT(delta >= 0);
896 Value* context = Bind(BuildCurrentContext(token_pos)); 879 Value* context = Bind(BuildCurrentContext(token_pos));
897 while (delta-- > 0) { 880 while (delta-- > 0) {
898 context = Bind(new(Z) LoadFieldInstr( 881 context = Bind(new (Z) LoadFieldInstr(context, Context::parent_offset(),
899 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()), 882 Type::ZoneHandle(Z, Type::null()),
900 token_pos)); 883 token_pos));
901 } 884 }
902 LoadFieldInstr* load = new(Z) LoadFieldInstr( 885 LoadFieldInstr* load =
903 context, 886 new (Z) LoadFieldInstr(context, Context::variable_offset(local.index()),
904 Context::variable_offset(local.index()), 887 local.type(), token_pos);
905 local.type(),
906 token_pos);
907 load->set_is_immutable(local.is_final()); 888 load->set_is_immutable(local.is_final());
908 return load; 889 return load;
909 } else { 890 } else {
910 return new(Z) LoadLocalInstr(local, token_pos); 891 return new (Z) LoadLocalInstr(local, token_pos);
911 } 892 }
912 } 893 }
913 894
914 895
915 // Stores current context into the 'variable' 896 // Stores current context into the 'variable'
916 void EffectGraphVisitor::BuildSaveContext( 897 void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable,
917 const LocalVariable& variable, 898 TokenPosition token_pos) {
918 TokenPosition token_pos) {
919 ASSERT(token_pos.IsSynthetic() || token_pos.IsNoSource()); 899 ASSERT(token_pos.IsSynthetic() || token_pos.IsNoSource());
920 Value* context = Bind(BuildCurrentContext(token_pos)); 900 Value* context = Bind(BuildCurrentContext(token_pos));
921 Do(BuildStoreLocal(variable, context, token_pos)); 901 Do(BuildStoreLocal(variable, context, token_pos));
922 } 902 }
923 903
924 904
925 // Loads context saved in 'context_variable' into the current context. 905 // Loads context saved in 'context_variable' into the current context.
926 void EffectGraphVisitor::BuildRestoreContext( 906 void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable,
927 const LocalVariable& variable, 907 TokenPosition token_pos) {
928 TokenPosition token_pos) {
929 Value* load_saved_context = Bind(BuildLoadLocal(variable, token_pos)); 908 Value* load_saved_context = Bind(BuildLoadLocal(variable, token_pos));
930 Do(BuildStoreContext(load_saved_context, token_pos)); 909 Do(BuildStoreContext(load_saved_context, token_pos));
931 } 910 }
932 911
933 912
934 Definition* EffectGraphVisitor::BuildStoreContext( 913 Definition* EffectGraphVisitor::BuildStoreContext(Value* value,
935 Value* value, TokenPosition token_pos) { 914 TokenPosition token_pos) {
936 return new(Z) StoreLocalInstr( 915 return new (Z) StoreLocalInstr(
937 *owner()->parsed_function().current_context_var(), value, token_pos); 916 *owner()->parsed_function().current_context_var(), value, token_pos);
938 } 917 }
939 918
940 919
941 Definition* EffectGraphVisitor::BuildCurrentContext(TokenPosition token_pos) { 920 Definition* EffectGraphVisitor::BuildCurrentContext(TokenPosition token_pos) {
942 return new(Z) LoadLocalInstr( 921 return new (Z) LoadLocalInstr(
943 *owner()->parsed_function().current_context_var(), 922 *owner()->parsed_function().current_context_var(), token_pos);
944 token_pos);
945 } 923 }
946 924
947 925
948 void TestGraphVisitor::ConnectBranchesTo( 926 void TestGraphVisitor::ConnectBranchesTo(
949 const GrowableArray<TargetEntryInstr**>& branches, 927 const GrowableArray<TargetEntryInstr**>& branches,
950 JoinEntryInstr* join) const { 928 JoinEntryInstr* join) const {
951 ASSERT(!branches.is_empty()); 929 ASSERT(!branches.is_empty());
952 for (intptr_t i = 0; i < branches.length(); i++) { 930 for (intptr_t i = 0; i < branches.length(); i++) {
953 TargetEntryInstr* target = 931 TargetEntryInstr* target = new (Z)
954 new(Z) TargetEntryInstr(owner()->AllocateBlockId(), 932 TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
955 owner()->try_index());
956 *(branches[i]) = target; 933 *(branches[i]) = target;
957 target->Goto(join); 934 target->Goto(join);
958 } 935 }
959 } 936 }
960 937
961 938
962 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const { 939 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const {
963 ConnectBranchesTo(true_successor_addresses_, join); 940 ConnectBranchesTo(true_successor_addresses_, join);
964 } 941 }
965 942
966 943
967 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const { 944 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const {
968 ConnectBranchesTo(false_successor_addresses_, join); 945 ConnectBranchesTo(false_successor_addresses_, join);
969 } 946 }
970 947
971 948
972 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor( 949 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor(
973 const GrowableArray<TargetEntryInstr**>& branches) const { 950 const GrowableArray<TargetEntryInstr**>& branches) const {
974 ASSERT(!branches.is_empty()); 951 ASSERT(!branches.is_empty());
975 952
976 if (branches.length() == 1) { 953 if (branches.length() == 1) {
977 TargetEntryInstr* target = 954 TargetEntryInstr* target = new (Z)
978 new(Z) TargetEntryInstr(owner()->AllocateBlockId(), 955 TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
979 owner()->try_index());
980 *(branches[0]) = target; 956 *(branches[0]) = target;
981 return target; 957 return target;
982 } 958 }
983 959
984 JoinEntryInstr* join = 960 JoinEntryInstr* join =
985 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 961 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
986 ConnectBranchesTo(branches, join); 962 ConnectBranchesTo(branches, join);
987 return join; 963 return join;
988 } 964 }
989 965
990 966
991 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const { 967 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const {
992 return CreateSuccessorFor(true_successor_addresses_); 968 return CreateSuccessorFor(true_successor_addresses_);
993 } 969 }
994 970
995 971
996 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const { 972 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const {
997 return CreateSuccessorFor(false_successor_addresses_); 973 return CreateSuccessorFor(false_successor_addresses_);
998 } 974 }
999 975
1000 976
1001 void TestGraphVisitor::ReturnValue(Value* value) { 977 void TestGraphVisitor::ReturnValue(Value* value) {
1002 Isolate* isolate = Isolate::Current(); 978 Isolate* isolate = Isolate::Current();
1003 if (isolate->type_checks() || isolate->asserts()) { 979 if (isolate->type_checks() || isolate->asserts()) {
1004 value = Bind(new(Z) AssertBooleanInstr(condition_token_pos(), value)); 980 value = Bind(new (Z) AssertBooleanInstr(condition_token_pos(), value));
1005 } 981 }
1006 Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True())); 982 Value* constant_true = Bind(new (Z) ConstantInstr(Bool::True()));
1007 StrictCompareInstr* comp = 983 StrictCompareInstr* comp = new (Z) StrictCompareInstr(
1008 new(Z) StrictCompareInstr(condition_token_pos(), 984 condition_token_pos(), Token::kEQ_STRICT, value, constant_true,
1009 Token::kEQ_STRICT, 985 false); // No number check.
1010 value, 986 BranchInstr* branch = new (Z) BranchInstr(comp);
1011 constant_true,
1012 false); // No number check.
1013 BranchInstr* branch = new(Z) BranchInstr(comp);
1014 AddInstruction(branch); 987 AddInstruction(branch);
1015 CloseFragment(); 988 CloseFragment();
1016 989
1017 true_successor_addresses_.Add(branch->true_successor_address()); 990 true_successor_addresses_.Add(branch->true_successor_address());
1018 false_successor_addresses_.Add(branch->false_successor_address()); 991 false_successor_addresses_.Add(branch->false_successor_address());
1019 } 992 }
1020 993
1021 994
1022 void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) { 995 void TestGraphVisitor::MergeBranchWithComparison(ComparisonInstr* comp) {
1023 BranchInstr* branch; 996 BranchInstr* branch;
1024 if (Token::IsStrictEqualityOperator(comp->kind())) { 997 if (Token::IsStrictEqualityOperator(comp->kind())) {
1025 ASSERT(comp->IsStrictCompare()); 998 ASSERT(comp->IsStrictCompare());
1026 branch = new(Z) BranchInstr(comp); 999 branch = new (Z) BranchInstr(comp);
1027 } else if (Token::IsEqualityOperator(comp->kind()) && 1000 } else if (Token::IsEqualityOperator(comp->kind()) &&
1028 (comp->left()->BindsToConstantNull() || 1001 (comp->left()->BindsToConstantNull() ||
1029 comp->right()->BindsToConstantNull())) { 1002 comp->right()->BindsToConstantNull())) {
1030 branch = new(Z) BranchInstr(new(Z) StrictCompareInstr( 1003 branch = new (Z) BranchInstr(new (Z) StrictCompareInstr(
1031 comp->token_pos(), 1004 comp->token_pos(),
1032 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT, 1005 (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT,
1033 comp->left(), 1006 comp->left(), comp->right(),
1034 comp->right(),
1035 false)); // No number check. 1007 false)); // No number check.
1036 } else { 1008 } else {
1037 branch = new(Z) BranchInstr(comp); 1009 branch = new (Z) BranchInstr(comp);
1038 branch->set_is_checked(Isolate::Current()->type_checks()); 1010 branch->set_is_checked(Isolate::Current()->type_checks());
1039 } 1011 }
1040 AddInstruction(branch); 1012 AddInstruction(branch);
1041 CloseFragment(); 1013 CloseFragment();
1042 true_successor_addresses_.Add(branch->true_successor_address()); 1014 true_successor_addresses_.Add(branch->true_successor_address());
1043 false_successor_addresses_.Add(branch->false_successor_address()); 1015 false_successor_addresses_.Add(branch->false_successor_address());
1044 } 1016 }
1045 1017
1046 1018
1047 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) { 1019 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) {
1048 ASSERT(!Isolate::Current()->type_checks()); 1020 ASSERT(!Isolate::Current()->type_checks());
1049 Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True())); 1021 Value* constant_true = Bind(new (Z) ConstantInstr(Bool::True()));
1050 StrictCompareInstr* comp = 1022 StrictCompareInstr* comp = new (Z) StrictCompareInstr(
1051 new(Z) StrictCompareInstr(condition_token_pos(), 1023 condition_token_pos(), Token::kNE_STRICT, neg->value(), constant_true,
1052 Token::kNE_STRICT, 1024 false); // No number check.
1053 neg->value(), 1025 BranchInstr* branch = new (Z) BranchInstr(comp);
1054 constant_true,
1055 false); // No number check.
1056 BranchInstr* branch = new(Z) BranchInstr(comp);
1057 AddInstruction(branch); 1026 AddInstruction(branch);
1058 CloseFragment(); 1027 CloseFragment();
1059 true_successor_addresses_.Add(branch->true_successor_address()); 1028 true_successor_addresses_.Add(branch->true_successor_address());
1060 false_successor_addresses_.Add(branch->false_successor_address()); 1029 false_successor_addresses_.Add(branch->false_successor_address());
1061 } 1030 }
1062 1031
1063 1032
1064 void TestGraphVisitor::ReturnDefinition(Definition* definition) { 1033 void TestGraphVisitor::ReturnDefinition(Definition* definition) {
1065 ComparisonInstr* comp = definition->AsComparison(); 1034 ComparisonInstr* comp = definition->AsComparison();
1066 if (comp != NULL) { 1035 if (comp != NULL) {
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 node->value()->Visit(&for_value); 1097 node->value()->Visit(&for_value);
1129 Append(for_value); 1098 Append(for_value);
1130 Value* return_value = for_value.value(); 1099 Value* return_value = for_value.value();
1131 1100
1132 // Call to stub that checks whether the debugger is in single 1101 // Call to stub that checks whether the debugger is in single
1133 // step mode. This call must happen before the contexts are 1102 // step mode. This call must happen before the contexts are
1134 // unchained so that captured variables can be inspected. 1103 // unchained so that captured variables can be inspected.
1135 // No debugger check is done in native functions or for return 1104 // No debugger check is done in native functions or for return
1136 // statements for which there is no associated source position. 1105 // statements for which there is no associated source position.
1137 const Function& function = owner()->function(); 1106 const Function& function = owner()->function();
1138 if (FLAG_support_debugger && 1107 if (FLAG_support_debugger && node->token_pos().IsDebugPause() &&
1139 node->token_pos().IsDebugPause() &&
1140 !function.is_native()) { 1108 !function.is_native()) {
1141 AddInstruction(new(Z) DebugStepCheckInstr(node->token_pos(), 1109 AddInstruction(new (Z) DebugStepCheckInstr(node->token_pos(),
1142 RawPcDescriptors::kRuntimeCall)); 1110 RawPcDescriptors::kRuntimeCall));
1143 } 1111 }
1144 1112
1145 NestedContextAdjustment context_adjustment(owner(), owner()->context_level()); 1113 NestedContextAdjustment context_adjustment(owner(), owner()->context_level());
1146 1114
1147 if (node->inlined_finally_list_length() > 0) { 1115 if (node->inlined_finally_list_length() > 0) {
1148 LocalVariable* temp = owner()->parsed_function().finally_return_temp_var(); 1116 LocalVariable* temp = owner()->parsed_function().finally_return_temp_var();
1149 ASSERT(temp != NULL); 1117 ASSERT(temp != NULL);
1150 Do(BuildStoreLocal(*temp, return_value, node->token_pos())); 1118 Do(BuildStoreLocal(*temp, return_value, node->token_pos()));
1151 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { 1119 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
1152 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)"); 1120 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)");
1153 EffectGraphVisitor for_effect(owner()); 1121 EffectGraphVisitor for_effect(owner());
1154 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); 1122 node->InlinedFinallyNodeAt(i)->Visit(&for_effect);
1155 Append(for_effect); 1123 Append(for_effect);
1156 if (!is_open()) { 1124 if (!is_open()) {
1157 return; 1125 return;
1158 } 1126 }
1159 } 1127 }
1160 return_value = Bind(BuildLoadLocal(*temp, node->token_pos())); 1128 return_value = Bind(BuildLoadLocal(*temp, node->token_pos()));
1161 } 1129 }
1162 1130
1163 if (Isolate::Current()->type_checks()) { 1131 if (Isolate::Current()->type_checks()) {
1164 const bool is_implicit_dynamic_getter = 1132 const bool is_implicit_dynamic_getter =
1165 (!function.is_static() && 1133 (!function.is_static() &&
1166 ((function.kind() == RawFunction::kImplicitGetter) || 1134 ((function.kind() == RawFunction::kImplicitGetter) ||
1167 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); 1135 (function.kind() == RawFunction::kImplicitStaticFinalGetter)));
1168 // Implicit getters do not need a type check at return, unless they compute 1136 // Implicit getters do not need a type check at return, unless they compute
1169 // the initial value of a static field. 1137 // the initial value of a static field.
1170 // The body of a constructor cannot modify the type of the 1138 // The body of a constructor cannot modify the type of the
1171 // constructed instance, which is passed in as an implicit parameter. 1139 // constructed instance, which is passed in as an implicit parameter.
1172 // However, factories may create an instance of the wrong type. 1140 // However, factories may create an instance of the wrong type.
1173 if (!is_implicit_dynamic_getter && !function.IsGenerativeConstructor()) { 1141 if (!is_implicit_dynamic_getter && !function.IsGenerativeConstructor()) {
1174 const AbstractType& dst_type = 1142 const AbstractType& dst_type =
1175 AbstractType::ZoneHandle(Z, function.result_type()); 1143 AbstractType::ZoneHandle(Z, function.result_type());
1176 return_value = BuildAssignableValue(node->value()->token_pos(), 1144 return_value =
1177 return_value, 1145 BuildAssignableValue(node->value()->token_pos(), return_value,
1178 dst_type, 1146 dst_type, Symbols::FunctionResult());
1179 Symbols::FunctionResult());
1180 } 1147 }
1181 } 1148 }
1182 1149
1183 // Async functions contain two types of return statements: 1150 // Async functions contain two types of return statements:
1184 // 1) Returns that should complete the completer once all finally blocks have 1151 // 1) Returns that should complete the completer once all finally blocks have
1185 // been inlined (call: :async_completer.complete(return_value)). These 1152 // been inlined (call: :async_completer.complete(return_value)). These
1186 // returns end up returning null in the end. 1153 // returns end up returning null in the end.
1187 // 2) "Continuation" returns that should not complete the completer but return 1154 // 2) "Continuation" returns that should not complete the completer but return
1188 // the value. 1155 // the value.
1189 // 1156 //
1190 // We distinguish those kinds of nodes via is_regular_return(). 1157 // We distinguish those kinds of nodes via is_regular_return().
1191 // 1158 //
1192 if (function.IsAsyncClosure() && 1159 if (function.IsAsyncClosure() &&
1193 (node->return_type() == ReturnNode::kRegular)) { 1160 (node->return_type() == ReturnNode::kRegular)) {
1194 // Temporary store the computed return value. 1161 // Temporary store the computed return value.
1195 Do(BuildStoreExprTemp(return_value, node->token_pos())); 1162 Do(BuildStoreExprTemp(return_value, node->token_pos()));
1196 1163
1197 LocalVariable* rcv_var = 1164 LocalVariable* rcv_var =
1198 node->scope()->LookupVariable(Symbols::AsyncCompleter(), false); 1165 node->scope()->LookupVariable(Symbols::AsyncCompleter(), false);
1199 ASSERT(rcv_var != NULL && rcv_var->is_captured()); 1166 ASSERT(rcv_var != NULL && rcv_var->is_captured());
1200 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1167 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1201 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); 1168 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1202 Value* rcv_value = Bind(BuildLoadLocal(*rcv_var, node->token_pos())); 1169 Value* rcv_value = Bind(BuildLoadLocal(*rcv_var, node->token_pos()));
1203 arguments->Add(PushArgument(rcv_value)); 1170 arguments->Add(PushArgument(rcv_value));
1204 Value* returned_value = Bind(BuildLoadExprTemp(node->token_pos())); 1171 Value* returned_value = Bind(BuildLoadExprTemp(node->token_pos()));
1205 arguments->Add(PushArgument(returned_value)); 1172 arguments->Add(PushArgument(returned_value));
1206 InstanceCallInstr* call = new(Z) InstanceCallInstr( 1173 InstanceCallInstr* call = new (Z) InstanceCallInstr(
1207 node->token_pos(), 1174 node->token_pos(), Symbols::CompleterComplete(), Token::kILLEGAL,
1208 Symbols::CompleterComplete(), 1175 arguments, Object::null_array(), 1, owner()->ic_data_array());
1209 Token::kILLEGAL,
1210 arguments,
1211 Object::null_array(),
1212 1,
1213 owner()->ic_data_array());
1214 Do(call); 1176 Do(call);
1215 1177
1216 // Rebind the return value for the actual return call to be null. 1178 // Rebind the return value for the actual return call to be null.
1217 return_value = BuildNullValue(node->token_pos()); 1179 return_value = BuildNullValue(node->token_pos());
1218 } 1180 }
1219 1181
1220 intptr_t current_context_level = owner()->context_level(); 1182 intptr_t current_context_level = owner()->context_level();
1221 ASSERT(current_context_level >= 0); 1183 ASSERT(current_context_level >= 0);
1222 if (HasContextScope()) { 1184 if (HasContextScope()) {
1223 UnchainContexts(current_context_level); 1185 UnchainContexts(current_context_level);
1224 } 1186 }
1225 1187
1226 AddReturnExit(node->token_pos(), return_value); 1188 AddReturnExit(node->token_pos(), return_value);
1227 1189
1228 if ((function.IsAsyncClosure() || 1190 if ((function.IsAsyncClosure() || function.IsSyncGenClosure() ||
1229 function.IsSyncGenClosure() || 1191 function.IsAsyncGenClosure()) &&
1230 function.IsAsyncGenClosure()) &&
1231 (node->return_type() == ReturnNode::kContinuationTarget)) { 1192 (node->return_type() == ReturnNode::kContinuationTarget)) {
1232 JoinEntryInstr* const join = new(Z) JoinEntryInstr( 1193 JoinEntryInstr* const join = new (Z)
1233 owner()->AllocateBlockId(), owner()->try_index()); 1194 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1234 owner()->await_joins()->Add(join); 1195 owner()->await_joins()->Add(join);
1235 exit_ = join; 1196 exit_ = join;
1236 } 1197 }
1237 } 1198 }
1238 1199
1239 1200
1240 // <Expression> ::= Literal { literal: Instance } 1201 // <Expression> ::= Literal { literal: Instance }
1241 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { 1202 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) {
1242 ReturnDefinition(new(Z) ConstantInstr(node->literal(), node->token_pos())); 1203 ReturnDefinition(new (Z) ConstantInstr(node->literal(), node->token_pos()));
1243 } 1204 }
1244 1205
1245 1206
1246 // Type nodes are used when a type is referenced as a literal. Type nodes 1207 // Type nodes are used when a type is referenced as a literal. Type nodes
1247 // can also be used for the right-hand side of instanceof comparisons, 1208 // can also be used for the right-hand side of instanceof comparisons,
1248 // but they are handled specially in that context, not here. 1209 // but they are handled specially in that context, not here.
1249 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { 1210 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) {
1250 return; 1211 return;
1251 } 1212 }
1252 1213
1253 1214
1254 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { 1215 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) {
1255 const AbstractType& type = node->type(); 1216 const AbstractType& type = node->type();
1256 // Type may be malbounded, but not malformed. 1217 // Type may be malbounded, but not malformed.
1257 ASSERT(type.IsFinalized() && !type.IsMalformed()); 1218 ASSERT(type.IsFinalized() && !type.IsMalformed());
1258 if (type.IsInstantiated()) { 1219 if (type.IsInstantiated()) {
1259 ReturnDefinition(new(Z) ConstantInstr(type)); 1220 ReturnDefinition(new (Z) ConstantInstr(type));
1260 } else { 1221 } else {
1261 const Class& instantiator_class = Class::ZoneHandle( 1222 const Class& instantiator_class =
1262 Z, owner()->function().Owner()); 1223 Class::ZoneHandle(Z, owner()->function().Owner());
1263 Value* instantiator_value = BuildInstantiatorTypeArguments( 1224 Value* instantiator_value = BuildInstantiatorTypeArguments(
1264 node->token_pos(), instantiator_class, NULL); 1225 node->token_pos(), instantiator_class, NULL);
1265 ReturnDefinition(new(Z) InstantiateTypeInstr( 1226 ReturnDefinition(new (Z) InstantiateTypeInstr(
1266 node->token_pos(), type, instantiator_class, instantiator_value)); 1227 node->token_pos(), type, instantiator_class, instantiator_value));
1267 } 1228 }
1268 } 1229 }
1269 1230
1270 1231
1271 // Returns true if the type check can be skipped, for example, if the 1232 // Returns true if the type check can be skipped, for example, if the
1272 // destination type is dynamic or if the compile type of the value is a subtype 1233 // destination type is dynamic or if the compile type of the value is a subtype
1273 // of the destination type. 1234 // of the destination type.
1274 bool EffectGraphVisitor::CanSkipTypeCheck(TokenPosition token_pos, 1235 bool EffectGraphVisitor::CanSkipTypeCheck(TokenPosition token_pos,
1275 Value* value, 1236 Value* value,
(...skipping 20 matching lines...) Expand all
1296 1257
1297 // If nothing is known about the value, as is the case for passed-in 1258 // If nothing is known about the value, as is the case for passed-in
1298 // parameters, and since dst_type is not one of the tested cases above, then 1259 // parameters, and since dst_type is not one of the tested cases above, then
1299 // the type test cannot be eliminated. 1260 // the type test cannot be eliminated.
1300 if (value == NULL) { 1261 if (value == NULL) {
1301 return false; 1262 return false;
1302 } 1263 }
1303 1264
1304 const bool eliminated = value->Type()->IsAssignableTo(dst_type); 1265 const bool eliminated = value->Type()->IsAssignableTo(dst_type);
1305 if (FLAG_trace_type_check_elimination) { 1266 if (FLAG_trace_type_check_elimination) {
1306 FlowGraphPrinter::PrintTypeCheck(owner()->parsed_function(), 1267 FlowGraphPrinter::PrintTypeCheck(owner()->parsed_function(), token_pos,
1307 token_pos, 1268 value, dst_type, dst_name, eliminated);
1308 value,
1309 dst_type,
1310 dst_name,
1311 eliminated);
1312 } 1269 }
1313 return eliminated; 1270 return eliminated;
1314 } 1271 }
1315 1272
1316 1273
1317 // <Expression> :: Assignable { expr: <Expression> 1274 // <Expression> :: Assignable { expr: <Expression>
1318 // type: AbstractType 1275 // type: AbstractType
1319 // dst_name: String } 1276 // dst_name: String }
1320 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { 1277 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) {
1321 ValueGraphVisitor for_value(owner()); 1278 ValueGraphVisitor for_value(owner());
1322 node->expr()->Visit(&for_value); 1279 node->expr()->Visit(&for_value);
1323 Append(for_value); 1280 Append(for_value);
1324 if (CanSkipTypeCheck(node->expr()->token_pos(), 1281 if (CanSkipTypeCheck(node->expr()->token_pos(), for_value.value(),
1325 for_value.value(), 1282 node->type(), node->dst_name())) {
1326 node->type(),
1327 node->dst_name())) {
1328 ReturnValue(for_value.value()); 1283 ReturnValue(for_value.value());
1329 } else { 1284 } else {
1330 ReturnDefinition(BuildAssertAssignable(node->expr()->token_pos(), 1285 ReturnDefinition(BuildAssertAssignable(node->expr()->token_pos(),
1331 for_value.value(), 1286 for_value.value(), node->type(),
1332 node->type(),
1333 node->dst_name())); 1287 node->dst_name()));
1334 } 1288 }
1335 } 1289 }
1336 1290
1337 1291
1338 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { 1292 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) {
1339 ValueGraphVisitor for_value(owner()); 1293 ValueGraphVisitor for_value(owner());
1340 node->expr()->Visit(&for_value); 1294 node->expr()->Visit(&for_value);
1341 Append(for_value); 1295 Append(for_value);
1342 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), 1296 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), for_value.value(),
1343 for_value.value(), 1297 node->type(), node->dst_name()));
1344 node->type(),
1345 node->dst_name()));
1346 } 1298 }
1347 1299
1348 1300
1349 // <Expression> :: BinaryOp { kind: Token::Kind 1301 // <Expression> :: BinaryOp { kind: Token::Kind
1350 // left: <Expression> 1302 // left: <Expression>
1351 // right: <Expression> } 1303 // right: <Expression> }
1352 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 1304 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
1353 // Operators "&&" and "||" cannot be overloaded therefore do not call 1305 // Operators "&&" and "||" cannot be overloaded therefore do not call
1354 // operator. 1306 // operator.
1355 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 1307 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
1356 // See ValueGraphVisitor::VisitBinaryOpNode. 1308 // See ValueGraphVisitor::VisitBinaryOpNode.
1357 TestGraphVisitor for_left(owner(), node->left()->token_pos()); 1309 TestGraphVisitor for_left(owner(), node->left()->token_pos());
1358 node->left()->Visit(&for_left); 1310 node->left()->Visit(&for_left);
1359 EffectGraphVisitor empty(owner()); 1311 EffectGraphVisitor empty(owner());
1360 Isolate* isolate = Isolate::Current(); 1312 Isolate* isolate = Isolate::Current();
1361 if (isolate->type_checks() || isolate->asserts()) { 1313 if (isolate->type_checks() || isolate->asserts()) {
1362 ValueGraphVisitor for_right(owner()); 1314 ValueGraphVisitor for_right(owner());
1363 node->right()->Visit(&for_right); 1315 node->right()->Visit(&for_right);
1364 Value* right_value = for_right.value(); 1316 Value* right_value = for_right.value();
1365 for_right.Do(new(Z) AssertBooleanInstr(node->right()->token_pos(), 1317 for_right.Do(
1366 right_value)); 1318 new (Z) AssertBooleanInstr(node->right()->token_pos(), right_value));
1367 if (node->kind() == Token::kAND) { 1319 if (node->kind() == Token::kAND) {
1368 Join(for_left, for_right, empty); 1320 Join(for_left, for_right, empty);
1369 } else { 1321 } else {
1370 Join(for_left, empty, for_right); 1322 Join(for_left, empty, for_right);
1371 } 1323 }
1372 } else { 1324 } else {
1373 EffectGraphVisitor for_right(owner()); 1325 EffectGraphVisitor for_right(owner());
1374 node->right()->Visit(&for_right); 1326 node->right()->Visit(&for_right);
1375 if (node->kind() == Token::kAND) { 1327 if (node->kind() == Token::kAND) {
1376 Join(for_left, for_right, empty); 1328 Join(for_left, for_right, empty);
1377 } else { 1329 } else {
1378 Join(for_left, empty, for_right); 1330 Join(for_left, empty, for_right);
1379 } 1331 }
1380 } 1332 }
1381 return; 1333 return;
1382 } 1334 }
1383 ASSERT(node->kind() != Token::kIFNULL); 1335 ASSERT(node->kind() != Token::kIFNULL);
1384 ValueGraphVisitor for_left_value(owner()); 1336 ValueGraphVisitor for_left_value(owner());
1385 node->left()->Visit(&for_left_value); 1337 node->left()->Visit(&for_left_value);
1386 Append(for_left_value); 1338 Append(for_left_value);
1387 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1339 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1388 1340
1389 ValueGraphVisitor for_right_value(owner()); 1341 ValueGraphVisitor for_right_value(owner());
1390 node->right()->Visit(&for_right_value); 1342 node->right()->Visit(&for_right_value);
1391 Append(for_right_value); 1343 Append(for_right_value);
1392 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 1344 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1393 1345
1394 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1346 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1395 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); 1347 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1396 arguments->Add(push_left); 1348 arguments->Add(push_left);
1397 arguments->Add(push_right); 1349 arguments->Add(push_right);
1398 const String& name = Symbols::Token(node->kind()); 1350 const String& name = Symbols::Token(node->kind());
1399 const intptr_t kNumArgsChecked = 2; 1351 const intptr_t kNumArgsChecked = 2;
1400 InstanceCallInstr* call = new(Z) InstanceCallInstr(node->token_pos(), 1352 InstanceCallInstr* call = new (Z) InstanceCallInstr(
1401 name, 1353 node->token_pos(), name, node->kind(), arguments, Object::null_array(),
1402 node->kind(), 1354 kNumArgsChecked, owner()->ic_data_array());
1403 arguments,
1404 Object::null_array(),
1405 kNumArgsChecked,
1406 owner()->ic_data_array());
1407 ReturnDefinition(call); 1355 ReturnDefinition(call);
1408 } 1356 }
1409 1357
1410 1358
1411 // Special handling for AND/OR. 1359 // Special handling for AND/OR.
1412 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 1360 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
1413 // Operators "&&" and "||" cannot be overloaded therefore do not call 1361 // Operators "&&" and "||" cannot be overloaded therefore do not call
1414 // operator. 1362 // operator.
1415 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 1363 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
1416 // Implement short-circuit logic: do not evaluate right if evaluation 1364 // Implement short-circuit logic: do not evaluate right if evaluation
1417 // of left is sufficient. 1365 // of left is sufficient.
1418 // AND: left ? right === true : false; 1366 // AND: left ? right === true : false;
1419 // OR: left ? true : right === true; 1367 // OR: left ? true : right === true;
1420 1368
1421 TestGraphVisitor for_test(owner(), node->left()->token_pos()); 1369 TestGraphVisitor for_test(owner(), node->left()->token_pos());
1422 node->left()->Visit(&for_test); 1370 node->left()->Visit(&for_test);
1423 1371
1424 ValueGraphVisitor for_right(owner()); 1372 ValueGraphVisitor for_right(owner());
1425 node->right()->Visit(&for_right); 1373 node->right()->Visit(&for_right);
1426 Value* right_value = for_right.value(); 1374 Value* right_value = for_right.value();
1427 Isolate* isolate = Isolate::Current(); 1375 Isolate* isolate = Isolate::Current();
1428 if (isolate->type_checks() || isolate->asserts()) { 1376 if (isolate->type_checks() || isolate->asserts()) {
1429 right_value = 1377 right_value = for_right.Bind(
1430 for_right.Bind(new(Z) AssertBooleanInstr(node->right()->token_pos(), 1378 new (Z) AssertBooleanInstr(node->right()->token_pos(), right_value));
1431 right_value));
1432 } 1379 }
1433 Value* constant_true = for_right.Bind(new(Z) ConstantInstr(Bool::True())); 1380 Value* constant_true = for_right.Bind(new (Z) ConstantInstr(Bool::True()));
1434 Value* compare = 1381 Value* compare = for_right.Bind(new (Z) StrictCompareInstr(
1435 for_right.Bind(new(Z) StrictCompareInstr(node->token_pos(), 1382 node->token_pos(), Token::kEQ_STRICT, right_value, constant_true,
1436 Token::kEQ_STRICT, 1383 false)); // No number check.
1437 right_value,
1438 constant_true,
1439 false)); // No number check.
1440 for_right.Do(BuildStoreExprTemp(compare, node->token_pos())); 1384 for_right.Do(BuildStoreExprTemp(compare, node->token_pos()));
1441 1385
1442 if (node->kind() == Token::kAND) { 1386 if (node->kind() == Token::kAND) {
1443 ValueGraphVisitor for_false(owner()); 1387 ValueGraphVisitor for_false(owner());
1444 Value* constant_false = 1388 Value* constant_false =
1445 for_false.Bind(new(Z) ConstantInstr(Bool::False())); 1389 for_false.Bind(new (Z) ConstantInstr(Bool::False()));
1446 for_false.Do(BuildStoreExprTemp(constant_false, node->token_pos())); 1390 for_false.Do(BuildStoreExprTemp(constant_false, node->token_pos()));
1447 Join(for_test, for_right, for_false); 1391 Join(for_test, for_right, for_false);
1448 } else { 1392 } else {
1449 ASSERT(node->kind() == Token::kOR); 1393 ASSERT(node->kind() == Token::kOR);
1450 ValueGraphVisitor for_true(owner()); 1394 ValueGraphVisitor for_true(owner());
1451 Value* constant_true = for_true.Bind(new(Z) ConstantInstr(Bool::True())); 1395 Value* constant_true = for_true.Bind(new (Z) ConstantInstr(Bool::True()));
1452 for_true.Do(BuildStoreExprTemp(constant_true, node->token_pos())); 1396 for_true.Do(BuildStoreExprTemp(constant_true, node->token_pos()));
1453 Join(for_test, for_true, for_right); 1397 Join(for_test, for_true, for_right);
1454 } 1398 }
1455 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); 1399 ReturnDefinition(BuildLoadExprTemp(node->token_pos()));
1456 return; 1400 return;
1457 } 1401 }
1458 1402
1459 EffectGraphVisitor::VisitBinaryOpNode(node); 1403 EffectGraphVisitor::VisitBinaryOpNode(node);
1460 } 1404 }
1461 1405
1462 1406
1463 void EffectGraphVisitor::BuildTypecheckPushArguments( 1407 void EffectGraphVisitor::BuildTypecheckPushArguments(
1464 TokenPosition token_pos, 1408 TokenPosition token_pos,
1465 PushArgumentInstr** push_instantiator_type_arguments_result) { 1409 PushArgumentInstr** push_instantiator_type_arguments_result) {
1466 const Class& instantiator_class = Class::Handle( 1410 const Class& instantiator_class =
1467 Z, owner()->function().Owner()); 1411 Class::Handle(Z, owner()->function().Owner());
1468 // Since called only when type tested against is not instantiated. 1412 // Since called only when type tested against is not instantiated.
1469 ASSERT(instantiator_class.IsGeneric()); 1413 ASSERT(instantiator_class.IsGeneric());
1470 Value* instantiator_type_arguments = NULL; 1414 Value* instantiator_type_arguments = NULL;
1471 Value* instantiator = BuildInstantiator(token_pos); 1415 Value* instantiator = BuildInstantiator(token_pos);
1472 if (instantiator == NULL) { 1416 if (instantiator == NULL) {
1473 // No instantiator when inside factory. 1417 // No instantiator when inside factory.
1474 instantiator_type_arguments = 1418 instantiator_type_arguments =
1475 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 1419 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
1476 } else { 1420 } else {
1477 instantiator_type_arguments = BuildInstantiatorTypeArguments( 1421 instantiator_type_arguments = BuildInstantiatorTypeArguments(
1478 token_pos, instantiator_class, instantiator); 1422 token_pos, instantiator_class, instantiator);
1479 } 1423 }
1480 *push_instantiator_type_arguments_result = 1424 *push_instantiator_type_arguments_result =
1481 PushArgument(instantiator_type_arguments); 1425 PushArgument(instantiator_type_arguments);
1482 } 1426 }
1483 1427
1484 1428
1485
1486 void EffectGraphVisitor::BuildTypecheckArguments( 1429 void EffectGraphVisitor::BuildTypecheckArguments(
1487 TokenPosition token_pos, 1430 TokenPosition token_pos,
1488 Value** instantiator_type_arguments_result) { 1431 Value** instantiator_type_arguments_result) {
1489 Value* instantiator = NULL; 1432 Value* instantiator = NULL;
1490 Value* instantiator_type_arguments = NULL; 1433 Value* instantiator_type_arguments = NULL;
1491 const Class& instantiator_class = Class::Handle( 1434 const Class& instantiator_class =
1492 Z, owner()->function().Owner()); 1435 Class::Handle(Z, owner()->function().Owner());
1493 // Since called only when type tested against is not instantiated. 1436 // Since called only when type tested against is not instantiated.
1494 ASSERT(instantiator_class.IsGeneric()); 1437 ASSERT(instantiator_class.IsGeneric());
1495 instantiator = BuildInstantiator(token_pos); 1438 instantiator = BuildInstantiator(token_pos);
1496 if (instantiator == NULL) { 1439 if (instantiator == NULL) {
1497 // No instantiator when inside factory. 1440 // No instantiator when inside factory.
1498 instantiator_type_arguments = 1441 instantiator_type_arguments =
1499 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 1442 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
1500 } else { 1443 } else {
1501 instantiator_type_arguments = BuildInstantiatorTypeArguments( 1444 instantiator_type_arguments = BuildInstantiatorTypeArguments(
1502 token_pos, instantiator_class, instantiator); 1445 token_pos, instantiator_class, instantiator);
1503 } 1446 }
1504 *instantiator_type_arguments_result = instantiator_type_arguments; 1447 *instantiator_type_arguments_result = instantiator_type_arguments;
1505 } 1448 }
1506 1449
1507 1450
1508 Value* EffectGraphVisitor::BuildNullValue(TokenPosition token_pos) { 1451 Value* EffectGraphVisitor::BuildNullValue(TokenPosition token_pos) {
1509 return Bind(new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()), 1452 return Bind(
1510 token_pos)); 1453 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()), token_pos));
1511 } 1454 }
1512 1455
1513 1456
1514 // Used for testing incoming arguments. 1457 // Used for testing incoming arguments.
1515 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( 1458 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable(
1516 TokenPosition token_pos, 1459 TokenPosition token_pos,
1517 Value* value, 1460 Value* value,
1518 const AbstractType& dst_type, 1461 const AbstractType& dst_type,
1519 const String& dst_name) { 1462 const String& dst_name) {
1520 // Build the type check computation. 1463 // Build the type check computation.
1521 Value* instantiator_type_arguments = NULL; 1464 Value* instantiator_type_arguments = NULL;
1522 if (dst_type.IsInstantiated()) { 1465 if (dst_type.IsInstantiated()) {
1523 instantiator_type_arguments = BuildNullValue(token_pos); 1466 instantiator_type_arguments = BuildNullValue(token_pos);
1524 } else { 1467 } else {
1525 BuildTypecheckArguments(token_pos, &instantiator_type_arguments); 1468 BuildTypecheckArguments(token_pos, &instantiator_type_arguments);
1526 } 1469 }
1527 1470
1528 const intptr_t deopt_id = Thread::Current()->GetNextDeoptId(); 1471 const intptr_t deopt_id = Thread::Current()->GetNextDeoptId();
1529 return new(Z) AssertAssignableInstr(token_pos, 1472 return new (Z)
1530 value, 1473 AssertAssignableInstr(token_pos, value, instantiator_type_arguments,
1531 instantiator_type_arguments, 1474 dst_type, dst_name, deopt_id);
1532 dst_type,
1533 dst_name,
1534 deopt_id);
1535 } 1475 }
1536 1476
1537 1477
1538 // Used for type casts and to test assignments. 1478 // Used for type casts and to test assignments.
1539 Value* EffectGraphVisitor::BuildAssignableValue(TokenPosition token_pos, 1479 Value* EffectGraphVisitor::BuildAssignableValue(TokenPosition token_pos,
1540 Value* value, 1480 Value* value,
1541 const AbstractType& dst_type, 1481 const AbstractType& dst_type,
1542 const String& dst_name) { 1482 const String& dst_name) {
1543 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { 1483 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) {
1544 return value; 1484 return value;
(...skipping 25 matching lines...) Expand all
1570 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); 1510 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
1571 const bool negate_result = (node->kind() == Token::kISNOT); 1511 const bool negate_result = (node->kind() == Token::kISNOT);
1572 // All objects are instances of type T if Object type is a subtype of type T. 1512 // All objects are instances of type T if Object type is a subtype of type T.
1573 const Type& object_type = Type::Handle(Z, Type::ObjectType()); 1513 const Type& object_type = Type::Handle(Z, Type::ObjectType());
1574 if (type.IsInstantiated() && 1514 if (type.IsInstantiated() &&
1575 object_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) { 1515 object_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) {
1576 // Must evaluate left side. 1516 // Must evaluate left side.
1577 EffectGraphVisitor for_left_value(owner()); 1517 EffectGraphVisitor for_left_value(owner());
1578 node->left()->Visit(&for_left_value); 1518 node->left()->Visit(&for_left_value);
1579 Append(for_left_value); 1519 Append(for_left_value);
1580 ReturnDefinition(new(Z) ConstantInstr(Bool::Get(!negate_result))); 1520 ReturnDefinition(new (Z) ConstantInstr(Bool::Get(!negate_result)));
1581 return; 1521 return;
1582 } 1522 }
1583 ValueGraphVisitor for_left_value(owner()); 1523 ValueGraphVisitor for_left_value(owner());
1584 node->left()->Visit(&for_left_value); 1524 node->left()->Visit(&for_left_value);
1585 Append(for_left_value); 1525 Append(for_left_value);
1586 1526
1587 if (type.IsNumberType() || type.IsIntType() || type.IsDoubleType() || 1527 if (type.IsNumberType() || type.IsIntType() || type.IsDoubleType() ||
1588 type.IsSmiType() || type.IsStringType()) { 1528 type.IsSmiType() || type.IsStringType()) {
1589 String& method_name = String::ZoneHandle(Z); 1529 String& method_name = String::ZoneHandle(Z);
1590 if (type.IsNumberType()) { 1530 if (type.IsNumberType()) {
1591 method_name = Symbols::_instanceOfNum().raw(); 1531 method_name = Symbols::_instanceOfNum().raw();
1592 } else if (type.IsIntType()) { 1532 } else if (type.IsIntType()) {
1593 method_name = Symbols::_instanceOfInt().raw(); 1533 method_name = Symbols::_instanceOfInt().raw();
1594 } else if (type.IsDoubleType()) { 1534 } else if (type.IsDoubleType()) {
1595 method_name = Symbols::_instanceOfDouble().raw(); 1535 method_name = Symbols::_instanceOfDouble().raw();
1596 } else if (type.IsSmiType()) { 1536 } else if (type.IsSmiType()) {
1597 method_name = Symbols::_instanceOfSmi().raw(); 1537 method_name = Symbols::_instanceOfSmi().raw();
1598 } else if (type.IsStringType()) { 1538 } else if (type.IsStringType()) {
1599 method_name = Symbols::_instanceOfString().raw(); 1539 method_name = Symbols::_instanceOfString().raw();
1600 } 1540 }
1601 ASSERT(!method_name.IsNull()); 1541 ASSERT(!method_name.IsNull());
1602 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1542 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1603 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1543 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1604 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); 1544 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1605 arguments->Add(push_left); 1545 arguments->Add(push_left);
1606 const Bool& negate = Bool::Get(node->kind() == Token::kISNOT); 1546 const Bool& negate = Bool::Get(node->kind() == Token::kISNOT);
1607 Value* negate_arg = Bind(new(Z) ConstantInstr(negate)); 1547 Value* negate_arg = Bind(new (Z) ConstantInstr(negate));
1608 arguments->Add(PushArgument(negate_arg)); 1548 arguments->Add(PushArgument(negate_arg));
1609 const intptr_t kNumArgsChecked = 1; 1549 const intptr_t kNumArgsChecked = 1;
1610 InstanceCallInstr* call = new(Z) InstanceCallInstr( 1550 InstanceCallInstr* call = new (Z) InstanceCallInstr(
1611 node->token_pos(), 1551 node->token_pos(), Library::PrivateCoreLibName(method_name),
1612 Library::PrivateCoreLibName(method_name), 1552 node->kind(), arguments,
1613 node->kind(),
1614 arguments,
1615 Object::null_array(), // No argument names. 1553 Object::null_array(), // No argument names.
1616 kNumArgsChecked, 1554 kNumArgsChecked, owner()->ic_data_array());
1617 owner()->ic_data_array());
1618 ReturnDefinition(call); 1555 ReturnDefinition(call);
1619 return; 1556 return;
1620 } 1557 }
1621 1558
1622 // We now know type is a real class (!num, !int, !smi, !string) 1559 // We now know type is a real class (!num, !int, !smi, !string)
1623 // and the type check could NOT be removed at compile time. 1560 // and the type check could NOT be removed at compile time.
1624 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1561 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1625 if (simpleInstanceOfType(type)) { 1562 if (simpleInstanceOfType(type)) {
1626 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); 1563 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1627 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1564 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1628 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); 1565 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1629 arguments->Add(push_left); 1566 arguments->Add(push_left);
1630 Value* type_const = Bind(new(Z) ConstantInstr(type)); 1567 Value* type_const = Bind(new (Z) ConstantInstr(type));
1631 arguments->Add(PushArgument(type_const)); 1568 arguments->Add(PushArgument(type_const));
1632 const intptr_t kNumArgsChecked = 2; 1569 const intptr_t kNumArgsChecked = 2;
1633 Definition* result = new(Z) InstanceCallInstr( 1570 Definition* result = new (Z) InstanceCallInstr(
1634 node->token_pos(), 1571 node->token_pos(),
1635 Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()), 1572 Library::PrivateCoreLibName(Symbols::_simpleInstanceOf()), node->kind(),
1636 node->kind(),
1637 arguments, 1573 arguments,
1638 Object::null_array(), // No argument names. 1574 Object::null_array(), // No argument names.
1639 kNumArgsChecked, 1575 kNumArgsChecked, owner()->ic_data_array());
1640 owner()->ic_data_array());
1641 if (negate_result) { 1576 if (negate_result) {
1642 result = new(Z) BooleanNegateInstr(Bind(result)); 1577 result = new (Z) BooleanNegateInstr(Bind(result));
1643 } 1578 }
1644 ReturnDefinition(result); 1579 ReturnDefinition(result);
1645 return; 1580 return;
1646 } 1581 }
1647 1582
1648 PushArgumentInstr* push_type_args = NULL; 1583 PushArgumentInstr* push_type_args = NULL;
1649 if (type.IsInstantiated()) { 1584 if (type.IsInstantiated()) {
1650 push_type_args = PushArgument(BuildNullValue(node->token_pos())); 1585 push_type_args = PushArgument(BuildNullValue(node->token_pos()));
1651 } else { 1586 } else {
1652 BuildTypecheckPushArguments(node->token_pos(), &push_type_args); 1587 BuildTypecheckPushArguments(node->token_pos(), &push_type_args);
1653 } 1588 }
1654 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1589 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1655 new(Z) ZoneGrowableArray<PushArgumentInstr*>(4); 1590 new (Z) ZoneGrowableArray<PushArgumentInstr*>(4);
1656 arguments->Add(push_left); 1591 arguments->Add(push_left);
1657 arguments->Add(push_type_args); 1592 arguments->Add(push_type_args);
1658 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); 1593 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1659 Value* type_const = Bind(new(Z) ConstantInstr(type)); 1594 Value* type_const = Bind(new (Z) ConstantInstr(type));
1660 arguments->Add(PushArgument(type_const)); 1595 arguments->Add(PushArgument(type_const));
1661 const Bool& negate = Bool::Get(node->kind() == Token::kISNOT); 1596 const Bool& negate = Bool::Get(node->kind() == Token::kISNOT);
1662 Value* negate_arg = Bind(new(Z) ConstantInstr(negate)); 1597 Value* negate_arg = Bind(new (Z) ConstantInstr(negate));
1663 arguments->Add(PushArgument(negate_arg)); 1598 arguments->Add(PushArgument(negate_arg));
1664 const intptr_t kNumArgsChecked = 1; 1599 const intptr_t kNumArgsChecked = 1;
1665 InstanceCallInstr* call = new(Z) InstanceCallInstr( 1600 InstanceCallInstr* call = new (Z) InstanceCallInstr(
1666 node->token_pos(), 1601 node->token_pos(), Library::PrivateCoreLibName(Symbols::_instanceOf()),
1667 Library::PrivateCoreLibName(Symbols::_instanceOf()), 1602 node->kind(), arguments,
1668 node->kind(),
1669 arguments,
1670 Object::null_array(), // No argument names. 1603 Object::null_array(), // No argument names.
1671 kNumArgsChecked, 1604 kNumArgsChecked, owner()->ic_data_array());
1672 owner()->ic_data_array());
1673 ReturnDefinition(call); 1605 ReturnDefinition(call);
1674 } 1606 }
1675 1607
1676 1608
1677 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { 1609 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) {
1678 ASSERT(Token::IsTypeCastOperator(node->kind())); 1610 ASSERT(Token::IsTypeCastOperator(node->kind()));
1679 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); 1611 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1680 const AbstractType& type = node->right()->AsTypeNode()->type(); 1612 const AbstractType& type = node->right()->AsTypeNode()->type();
1681 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); 1613 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
1682 ValueGraphVisitor for_value(owner()); 1614 ValueGraphVisitor for_value(owner());
1683 node->left()->Visit(&for_value); 1615 node->left()->Visit(&for_value);
1684 Append(for_value); 1616 Append(for_value);
1685 if (CanSkipTypeCheck(node->token_pos(), 1617 if (CanSkipTypeCheck(node->token_pos(), for_value.value(), type,
1686 for_value.value(),
1687 type,
1688 Symbols::InTypeCast())) { 1618 Symbols::InTypeCast())) {
1689 ReturnValue(for_value.value()); 1619 ReturnValue(for_value.value());
1690 return; 1620 return;
1691 } 1621 }
1692 PushArgumentInstr* push_left = PushArgument(for_value.value()); 1622 PushArgumentInstr* push_left = PushArgument(for_value.value());
1693 PushArgumentInstr* push_type_args = NULL; 1623 PushArgumentInstr* push_type_args = NULL;
1694 if (type.IsInstantiated()) { 1624 if (type.IsInstantiated()) {
1695 push_type_args = PushArgument(BuildNullValue(node->token_pos())); 1625 push_type_args = PushArgument(BuildNullValue(node->token_pos()));
1696 } else { 1626 } else {
1697 BuildTypecheckPushArguments(node->token_pos(), &push_type_args); 1627 BuildTypecheckPushArguments(node->token_pos(), &push_type_args);
1698 } 1628 }
1699 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1629 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1700 new(Z) ZoneGrowableArray<PushArgumentInstr*>(3); 1630 new (Z) ZoneGrowableArray<PushArgumentInstr*>(3);
1701 arguments->Add(push_left); 1631 arguments->Add(push_left);
1702 arguments->Add(push_type_args); 1632 arguments->Add(push_type_args);
1703 Value* type_arg = Bind(new(Z) ConstantInstr(type)); 1633 Value* type_arg = Bind(new (Z) ConstantInstr(type));
1704 arguments->Add(PushArgument(type_arg)); 1634 arguments->Add(PushArgument(type_arg));
1705 const intptr_t kNumArgsChecked = 1; 1635 const intptr_t kNumArgsChecked = 1;
1706 InstanceCallInstr* call = new(Z) InstanceCallInstr( 1636 InstanceCallInstr* call = new (Z) InstanceCallInstr(
1707 node->token_pos(), 1637 node->token_pos(), Library::PrivateCoreLibName(Symbols::_as()),
1708 Library::PrivateCoreLibName(Symbols::_as()), 1638 node->kind(), arguments,
1709 node->kind(),
1710 arguments,
1711 Object::null_array(), // No argument names. 1639 Object::null_array(), // No argument names.
1712 kNumArgsChecked, 1640 kNumArgsChecked, owner()->ic_data_array());
1713 owner()->ic_data_array());
1714 ReturnDefinition(call); 1641 ReturnDefinition(call);
1715 } 1642 }
1716 1643
1717 1644
1718 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare( 1645 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare(
1719 AstNode* left, 1646 AstNode* left,
1720 AstNode* right, 1647 AstNode* right,
1721 Token::Kind kind, 1648 Token::Kind kind,
1722 TokenPosition token_pos) { 1649 TokenPosition token_pos) {
1723 ValueGraphVisitor for_left_value(owner()); 1650 ValueGraphVisitor for_left_value(owner());
1724 left->Visit(&for_left_value); 1651 left->Visit(&for_left_value);
1725 Append(for_left_value); 1652 Append(for_left_value);
1726 ValueGraphVisitor for_right_value(owner()); 1653 ValueGraphVisitor for_right_value(owner());
1727 right->Visit(&for_right_value); 1654 right->Visit(&for_right_value);
1728 Append(for_right_value); 1655 Append(for_right_value);
1729 StrictCompareInstr* comp = new(Z) StrictCompareInstr(token_pos, 1656 StrictCompareInstr* comp = new (Z) StrictCompareInstr(
1730 kind, 1657 token_pos, kind, for_left_value.value(), for_right_value.value(),
1731 for_left_value.value(), 1658 true); // Number check.
1732 for_right_value.value(),
1733 true); // Number check.
1734 return comp; 1659 return comp;
1735 } 1660 }
1736 1661
1737 1662
1738 // <Expression> :: Comparison { kind: Token::Kind 1663 // <Expression> :: Comparison { kind: Token::Kind
1739 // left: <Expression> 1664 // left: <Expression>
1740 // right: <Expression> } 1665 // right: <Expression> }
1741 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { 1666 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
1742 if (Token::IsTypeTestOperator(node->kind())) { 1667 if (Token::IsTypeTestOperator(node->kind())) {
1743 BuildTypeTest(node); 1668 BuildTypeTest(node);
(...skipping 12 matching lines...) Expand all
1756 } 1681 }
1757 1682
1758 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) { 1683 if ((node->kind() == Token::kEQ) || (node->kind() == Token::kNE)) {
1759 // Eagerly fold null-comparisons. 1684 // Eagerly fold null-comparisons.
1760 LiteralNode* left_lit = node->left()->AsLiteralNode(); 1685 LiteralNode* left_lit = node->left()->AsLiteralNode();
1761 LiteralNode* right_lit = node->right()->AsLiteralNode(); 1686 LiteralNode* right_lit = node->right()->AsLiteralNode();
1762 if (((left_lit != NULL) && left_lit->literal().IsNull()) || 1687 if (((left_lit != NULL) && left_lit->literal().IsNull()) ||
1763 ((right_lit != NULL) && right_lit->literal().IsNull())) { 1688 ((right_lit != NULL) && right_lit->literal().IsNull())) {
1764 Token::Kind kind = 1689 Token::Kind kind =
1765 (node->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT; 1690 (node->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT;
1766 StrictCompareInstr* compare = 1691 StrictCompareInstr* compare = BuildStrictCompare(
1767 BuildStrictCompare(node->left(), node->right(), 1692 node->left(), node->right(), kind, node->token_pos());
1768 kind, node->token_pos());
1769 ReturnDefinition(compare); 1693 ReturnDefinition(compare);
1770 return; 1694 return;
1771 } 1695 }
1772 1696
1773 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1697 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1774 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); 1698 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1775 1699
1776 ValueGraphVisitor for_left_value(owner()); 1700 ValueGraphVisitor for_left_value(owner());
1777 node->left()->Visit(&for_left_value); 1701 node->left()->Visit(&for_left_value);
1778 Append(for_left_value); 1702 Append(for_left_value);
1779 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1703 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1780 arguments->Add(push_left); 1704 arguments->Add(push_left);
1781 1705
1782 ValueGraphVisitor for_right_value(owner()); 1706 ValueGraphVisitor for_right_value(owner());
1783 node->right()->Visit(&for_right_value); 1707 node->right()->Visit(&for_right_value);
1784 Append(for_right_value); 1708 Append(for_right_value);
1785 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 1709 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1786 arguments->Add(push_right); 1710 arguments->Add(push_right);
1787 1711
1788 const intptr_t kNumArgsChecked = 2; 1712 const intptr_t kNumArgsChecked = 2;
1789 Definition* result = new(Z) InstanceCallInstr( 1713 Definition* result = new (Z)
1790 node->token_pos(), 1714 InstanceCallInstr(node->token_pos(), Symbols::EqualOperator(),
1791 Symbols::EqualOperator(), 1715 Token::kEQ, // Result is negated later for kNE.
1792 Token::kEQ, // Result is negated later for kNE. 1716 arguments, Object::null_array(), kNumArgsChecked,
1793 arguments, 1717 owner()->ic_data_array());
1794 Object::null_array(),
1795 kNumArgsChecked,
1796 owner()->ic_data_array());
1797 if (node->kind() == Token::kNE) { 1718 if (node->kind() == Token::kNE) {
1798 Isolate* isolate = Isolate::Current(); 1719 Isolate* isolate = Isolate::Current();
1799 if (isolate->type_checks() || isolate->asserts()) { 1720 if (isolate->type_checks() || isolate->asserts()) {
1800 Value* value = Bind(result); 1721 Value* value = Bind(result);
1801 result = new(Z) AssertBooleanInstr(node->token_pos(), value); 1722 result = new (Z) AssertBooleanInstr(node->token_pos(), value);
1802 } 1723 }
1803 Value* value = Bind(result); 1724 Value* value = Bind(result);
1804 result = new(Z) BooleanNegateInstr(value); 1725 result = new (Z) BooleanNegateInstr(value);
1805 } 1726 }
1806 ReturnDefinition(result); 1727 ReturnDefinition(result);
1807 return; 1728 return;
1808 } 1729 }
1809 1730
1810 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1731 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1811 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); 1732 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
1812 1733
1813 ValueGraphVisitor for_left_value(owner()); 1734 ValueGraphVisitor for_left_value(owner());
1814 node->left()->Visit(&for_left_value); 1735 node->left()->Visit(&for_left_value);
1815 Append(for_left_value); 1736 Append(for_left_value);
1816 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); 1737 PushArgumentInstr* push_left = PushArgument(for_left_value.value());
1817 arguments->Add(push_left); 1738 arguments->Add(push_left);
1818 1739
1819 ValueGraphVisitor for_right_value(owner()); 1740 ValueGraphVisitor for_right_value(owner());
1820 node->right()->Visit(&for_right_value); 1741 node->right()->Visit(&for_right_value);
1821 Append(for_right_value); 1742 Append(for_right_value);
1822 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); 1743 PushArgumentInstr* push_right = PushArgument(for_right_value.value());
1823 arguments->Add(push_right); 1744 arguments->Add(push_right);
1824 1745
1825 ASSERT(Token::IsRelationalOperator(node->kind())); 1746 ASSERT(Token::IsRelationalOperator(node->kind()));
1826 InstanceCallInstr* comp = new(Z) InstanceCallInstr( 1747 InstanceCallInstr* comp = new (Z) InstanceCallInstr(
1827 node->token_pos(), 1748 node->token_pos(), Symbols::Token(node->kind()), node->kind(), arguments,
1828 Symbols::Token(node->kind()), 1749 Object::null_array(), 2, owner()->ic_data_array());
1829 node->kind(),
1830 arguments,
1831 Object::null_array(),
1832 2,
1833 owner()->ic_data_array());
1834 ReturnDefinition(comp); 1750 ReturnDefinition(comp);
1835 } 1751 }
1836 1752
1837 1753
1838 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { 1754 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
1839 // "!" cannot be overloaded, therefore do not call operator. 1755 // "!" cannot be overloaded, therefore do not call operator.
1840 if (node->kind() == Token::kNOT) { 1756 if (node->kind() == Token::kNOT) {
1841 ValueGraphVisitor for_value(owner()); 1757 ValueGraphVisitor for_value(owner());
1842 node->operand()->Visit(&for_value); 1758 node->operand()->Visit(&for_value);
1843 Append(for_value); 1759 Append(for_value);
1844 Value* value = for_value.value(); 1760 Value* value = for_value.value();
1845 Isolate* isolate = Isolate::Current(); 1761 Isolate* isolate = Isolate::Current();
1846 if (isolate->type_checks() || isolate->asserts()) { 1762 if (isolate->type_checks() || isolate->asserts()) {
1847 value = 1763 value =
1848 Bind(new(Z) AssertBooleanInstr(node->operand()->token_pos(), value)); 1764 Bind(new (Z) AssertBooleanInstr(node->operand()->token_pos(), value));
1849 } 1765 }
1850 BooleanNegateInstr* negate = new(Z) BooleanNegateInstr(value); 1766 BooleanNegateInstr* negate = new (Z) BooleanNegateInstr(value);
1851 ReturnDefinition(negate); 1767 ReturnDefinition(negate);
1852 return; 1768 return;
1853 } 1769 }
1854 1770
1855 ValueGraphVisitor for_value(owner()); 1771 ValueGraphVisitor for_value(owner());
1856 node->operand()->Visit(&for_value); 1772 node->operand()->Visit(&for_value);
1857 Append(for_value); 1773 Append(for_value);
1858 PushArgumentInstr* push_value = PushArgument(for_value.value()); 1774 PushArgumentInstr* push_value = PushArgument(for_value.value());
1859 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1775 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1860 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); 1776 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1);
1861 arguments->Add(push_value); 1777 arguments->Add(push_value);
1862 InstanceCallInstr* call = new(Z) InstanceCallInstr( 1778 InstanceCallInstr* call = new (Z) InstanceCallInstr(
1863 node->token_pos(), 1779 node->token_pos(), Symbols::Token(node->kind()), node->kind(), arguments,
1864 Symbols::Token(node->kind()), 1780 Object::null_array(), 1, owner()->ic_data_array());
1865 node->kind(),
1866 arguments,
1867 Object::null_array(),
1868 1,
1869 owner()->ic_data_array());
1870 ReturnDefinition(call); 1781 ReturnDefinition(call);
1871 } 1782 }
1872 1783
1873 1784
1874 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 1785 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
1875 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); 1786 TestGraphVisitor for_test(owner(), node->condition()->token_pos());
1876 node->condition()->Visit(&for_test); 1787 node->condition()->Visit(&for_test);
1877 1788
1878 // Translate the subexpressions for their effects. 1789 // Translate the subexpressions for their effects.
1879 EffectGraphVisitor for_true(owner()); 1790 EffectGraphVisitor for_true(owner());
1880 node->true_expr()->Visit(&for_true); 1791 node->true_expr()->Visit(&for_true);
1881 EffectGraphVisitor for_false(owner()); 1792 EffectGraphVisitor for_false(owner());
1882 node->false_expr()->Visit(&for_false); 1793 node->false_expr()->Visit(&for_false);
1883 1794
1884 Join(for_test, for_true, for_false); 1795 Join(for_test, for_true, for_false);
1885 } 1796 }
1886 1797
1887 1798
1888 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 1799 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
1889 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); 1800 TestGraphVisitor for_test(owner(), node->condition()->token_pos());
1890 node->condition()->Visit(&for_test); 1801 node->condition()->Visit(&for_test);
1891 1802
1892 ValueGraphVisitor for_true(owner()); 1803 ValueGraphVisitor for_true(owner());
1893 node->true_expr()->Visit(&for_true); 1804 node->true_expr()->Visit(&for_true);
1894 ASSERT(for_true.is_open()); 1805 ASSERT(for_true.is_open());
1895 for_true.Do(BuildStoreExprTemp(for_true.value(), 1806 for_true.Do(
1896 node->true_expr()->token_pos())); 1807 BuildStoreExprTemp(for_true.value(), node->true_expr()->token_pos()));
1897 1808
1898 ValueGraphVisitor for_false(owner()); 1809 ValueGraphVisitor for_false(owner());
1899 node->false_expr()->Visit(&for_false); 1810 node->false_expr()->Visit(&for_false);
1900 ASSERT(for_false.is_open()); 1811 ASSERT(for_false.is_open());
1901 for_false.Do(BuildStoreExprTemp(for_false.value(), 1812 for_false.Do(
1902 node->false_expr()->token_pos())); 1813 BuildStoreExprTemp(for_false.value(), node->false_expr()->token_pos()));
1903 1814
1904 Join(for_test, for_true, for_false); 1815 Join(for_test, for_true, for_false);
1905 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); 1816 ReturnDefinition(BuildLoadExprTemp(node->token_pos()));
1906 } 1817 }
1907 1818
1908 1819
1909 // <Statement> ::= If { condition: <Expression> 1820 // <Statement> ::= If { condition: <Expression>
1910 // true_branch: <Sequence> 1821 // true_branch: <Sequence>
1911 // false_branch: <Sequence> } 1822 // false_branch: <Sequence> }
1912 void EffectGraphVisitor::VisitIfNode(IfNode* node) { 1823 void EffectGraphVisitor::VisitIfNode(IfNode* node) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1957 // 1868 //
1958 // Note: The specification of switch/case is under discussion and may change 1869 // Note: The specification of switch/case is under discussion and may change
1959 // drastically. 1870 // drastically.
1960 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) { 1871 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) {
1961 const intptr_t len = node->case_expressions()->length(); 1872 const intptr_t len = node->case_expressions()->length();
1962 // Create case statements instructions. 1873 // Create case statements instructions.
1963 EffectGraphVisitor for_case_statements(owner()); 1874 EffectGraphVisitor for_case_statements(owner());
1964 // Compute the start of the statements fragment. 1875 // Compute the start of the statements fragment.
1965 JoinEntryInstr* statement_start = NULL; 1876 JoinEntryInstr* statement_start = NULL;
1966 if (node->label() == NULL) { 1877 if (node->label() == NULL) {
1967 statement_start = new(Z) JoinEntryInstr(owner()->AllocateBlockId(), 1878 statement_start = new (Z)
1968 owner()->try_index()); 1879 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
1969 } else { 1880 } else {
1970 // The case nodes are nested inside a SequenceNode that is the body of a 1881 // The case nodes are nested inside a SequenceNode that is the body of a
1971 // SwitchNode. The SwitchNode on the nesting stack contains the 1882 // SwitchNode. The SwitchNode on the nesting stack contains the
1972 // continue labels for all the case clauses. 1883 // continue labels for all the case clauses.
1973 statement_start = 1884 statement_start =
1974 owner()->nesting_stack()->outer()->ContinueTargetFor(node->label()); 1885 owner()->nesting_stack()->outer()->ContinueTargetFor(node->label());
1975 } 1886 }
1976 ASSERT(statement_start != NULL); 1887 ASSERT(statement_start != NULL);
1977 node->statements()->Visit(&for_case_statements); 1888 node->statements()->Visit(&for_case_statements);
1978 Instruction* statement_exit = 1889 Instruction* statement_exit =
(...skipping 30 matching lines...) Expand all
2009 // Handle last (or only) case: false goes to exit or to statement if this 1920 // Handle last (or only) case: false goes to exit or to statement if this
2010 // node contains default. 1921 // node contains default.
2011 if (len > 0) { 1922 if (len > 0) {
2012 ASSERT(next_target != NULL); 1923 ASSERT(next_target != NULL);
2013 if (node->contains_default()) { 1924 if (node->contains_default()) {
2014 // True and false go to statement start. 1925 // True and false go to statement start.
2015 next_target->Goto(statement_start); 1926 next_target->Goto(statement_start);
2016 exit_instruction = statement_exit; 1927 exit_instruction = statement_exit;
2017 } else { 1928 } else {
2018 if (statement_exit != NULL) { 1929 if (statement_exit != NULL) {
2019 JoinEntryInstr* join = new(Z) JoinEntryInstr(owner()->AllocateBlockId(), 1930 JoinEntryInstr* join = new (Z)
2020 owner()->try_index()); 1931 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
2021 statement_exit->Goto(join); 1932 statement_exit->Goto(join);
2022 next_target->Goto(join); 1933 next_target->Goto(join);
2023 exit_instruction = join; 1934 exit_instruction = join;
2024 } else { 1935 } else {
2025 exit_instruction = next_target; 1936 exit_instruction = next_target;
2026 } 1937 }
2027 } 1938 }
2028 } else { 1939 } else {
2029 // A CaseNode without case expressions must contain default. 1940 // A CaseNode without case expressions must contain default.
2030 ASSERT(node->contains_default()); 1941 ASSERT(node->contains_default());
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2093 // Traverse the body first in order to generate continue and break labels. 2004 // Traverse the body first in order to generate continue and break labels.
2094 EffectGraphVisitor for_body(owner()); 2005 EffectGraphVisitor for_body(owner());
2095 node->body()->Visit(&for_body); 2006 node->body()->Visit(&for_body);
2096 2007
2097 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); 2008 TestGraphVisitor for_test(owner(), node->condition()->token_pos());
2098 node->condition()->Visit(&for_test); 2009 node->condition()->Visit(&for_test);
2099 ASSERT(is_open()); 2010 ASSERT(is_open());
2100 2011
2101 // Tie do-while loop (test is after the body). 2012 // Tie do-while loop (test is after the body).
2102 JoinEntryInstr* body_entry_join = 2013 JoinEntryInstr* body_entry_join =
2103 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), 2014 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
2104 owner()->try_index());
2105 Goto(body_entry_join); 2015 Goto(body_entry_join);
2106 Instruction* body_exit = AppendFragment(body_entry_join, for_body); 2016 Instruction* body_exit = AppendFragment(body_entry_join, for_body);
2107 2017
2108 JoinEntryInstr* join = nested_loop.continue_target(); 2018 JoinEntryInstr* join = nested_loop.continue_target();
2109 if ((body_exit != NULL) || (join != NULL)) { 2019 if ((body_exit != NULL) || (join != NULL)) {
2110 if (join == NULL) { 2020 if (join == NULL) {
2111 join = new(Z) JoinEntryInstr(owner()->AllocateBlockId(), 2021 join = new (Z)
2112 owner()->try_index()); 2022 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
2113 } 2023 }
2114 CheckStackOverflowInstr* check = new(Z) CheckStackOverflowInstr( 2024 CheckStackOverflowInstr* check = new (Z)
2115 node->token_pos(), owner()->loop_depth()); 2025 CheckStackOverflowInstr(node->token_pos(), owner()->loop_depth());
2116 join->LinkTo(check); 2026 join->LinkTo(check);
2117 check->LinkTo(for_test.entry()); 2027 check->LinkTo(for_test.entry());
2118 if (body_exit != NULL) { 2028 if (body_exit != NULL) {
2119 body_exit->Goto(join); 2029 body_exit->Goto(join);
2120 } 2030 }
2121 } 2031 }
2122 2032
2123 for_test.IfTrueGoto(body_entry_join); 2033 for_test.IfTrueGoto(body_entry_join);
2124 join = nested_loop.break_target(); 2034 join = nested_loop.break_target();
2125 if (join == NULL) { 2035 if (join == NULL) {
(...skipping 27 matching lines...) Expand all
2153 // Compose body to set any jump labels. 2063 // Compose body to set any jump labels.
2154 EffectGraphVisitor for_body(owner()); 2064 EffectGraphVisitor for_body(owner());
2155 node->body()->Visit(&for_body); 2065 node->body()->Visit(&for_body);
2156 2066
2157 EffectGraphVisitor for_increment(owner()); 2067 EffectGraphVisitor for_increment(owner());
2158 node->increment()->Visit(&for_increment); 2068 node->increment()->Visit(&for_increment);
2159 2069
2160 // Join the loop body and increment and then tie the loop. 2070 // Join the loop body and increment and then tie the loop.
2161 JoinEntryInstr* continue_join = nested_loop.continue_target(); 2071 JoinEntryInstr* continue_join = nested_loop.continue_target();
2162 if ((continue_join != NULL) || for_body.is_open()) { 2072 if ((continue_join != NULL) || for_body.is_open()) {
2163 JoinEntryInstr* loop_entry = 2073 JoinEntryInstr* loop_entry = new (Z)
2164 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 2074 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
2165 if (continue_join != NULL) { 2075 if (continue_join != NULL) {
2166 if (for_body.is_open()) for_body.Goto(continue_join); 2076 if (for_body.is_open()) for_body.Goto(continue_join);
2167 Instruction* current = AppendFragment(continue_join, for_increment); 2077 Instruction* current = AppendFragment(continue_join, for_increment);
2168 current->Goto(loop_entry); 2078 current->Goto(loop_entry);
2169 } else { 2079 } else {
2170 for_body.Append(for_increment); 2080 for_body.Append(for_increment);
2171 for_body.Goto(loop_entry); 2081 for_body.Goto(loop_entry);
2172 } 2082 }
2173 Goto(loop_entry); 2083 Goto(loop_entry);
2174 exit_ = loop_entry; 2084 exit_ = loop_entry;
2175 // Note: the stack overflow check happens on the back branch that jumps 2085 // Note: the stack overflow check happens on the back branch that jumps
2176 // to the increment instruction. The token position for the overflow 2086 // to the increment instruction. The token position for the overflow
2177 // check must match the position of the increment expression, so that 2087 // check must match the position of the increment expression, so that
2178 // the context level (if any) matches the that of the increment 2088 // the context level (if any) matches the that of the increment
2179 // expression. 2089 // expression.
2180 AddInstruction( 2090 AddInstruction(new (Z) CheckStackOverflowInstr(
2181 new(Z) CheckStackOverflowInstr(node->increment()->token_pos(), 2091 node->increment()->token_pos(), owner()->loop_depth()));
2182 owner()->loop_depth()));
2183 } 2092 }
2184 2093
2185 if (node->condition() == NULL) { 2094 if (node->condition() == NULL) {
2186 // Endless loop, no test. 2095 // Endless loop, no test.
2187 Append(for_body); 2096 Append(for_body);
2188 exit_ = nested_loop.break_target(); // May be NULL. 2097 exit_ = nested_loop.break_target(); // May be NULL.
2189 } else { 2098 } else {
2190 EffectGraphVisitor for_test_preamble(owner()); 2099 EffectGraphVisitor for_test_preamble(owner());
2191 if (node->condition_preamble() != NULL) { 2100 if (node->condition_preamble() != NULL) {
2192 node->condition_preamble()->Visit(&for_test_preamble); 2101 node->condition_preamble()->Visit(&for_test_preamble);
(...skipping 30 matching lines...) Expand all
2223 // Unchain the context(s) up to the outer context level of the scope which 2132 // Unchain the context(s) up to the outer context level of the scope which
2224 // contains the destination label. 2133 // contains the destination label.
2225 SourceLabel* label = node->label(); 2134 SourceLabel* label = node->label();
2226 ASSERT(label->owner() != NULL); 2135 ASSERT(label->owner() != NULL);
2227 AdjustContextLevel(label->owner()); 2136 AdjustContextLevel(label->owner());
2228 2137
2229 JoinEntryInstr* jump_target = NULL; 2138 JoinEntryInstr* jump_target = NULL;
2230 NestedStatement* current = owner()->nesting_stack(); 2139 NestedStatement* current = owner()->nesting_stack();
2231 while (current != NULL) { 2140 while (current != NULL) {
2232 jump_target = (node->kind() == Token::kBREAK) 2141 jump_target = (node->kind() == Token::kBREAK)
2233 ? current->BreakTargetFor(node->label()) 2142 ? current->BreakTargetFor(node->label())
2234 : current->ContinueTargetFor(node->label()); 2143 : current->ContinueTargetFor(node->label());
2235 if (jump_target != NULL) break; 2144 if (jump_target != NULL) break;
2236 current = current->outer(); 2145 current = current->outer();
2237 } 2146 }
2238 ASSERT(jump_target != NULL); 2147 ASSERT(jump_target != NULL);
2239 Goto(jump_target); 2148 Goto(jump_target);
2240 } 2149 }
2241 2150
2242 2151
2243 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { 2152 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
2244 UNREACHABLE(); 2153 UNREACHABLE();
2245 } 2154 }
2246 2155
2247 2156
2248 void EffectGraphVisitor::VisitAwaitNode(AwaitNode* node) { 2157 void EffectGraphVisitor::VisitAwaitNode(AwaitNode* node) {
2249 // Await nodes are temporary during parsing. 2158 // Await nodes are temporary during parsing.
2250 UNREACHABLE(); 2159 UNREACHABLE();
2251 } 2160 }
2252 2161
2253 2162
2254 void EffectGraphVisitor::VisitAwaitMarkerNode(AwaitMarkerNode* node) { 2163 void EffectGraphVisitor::VisitAwaitMarkerNode(AwaitMarkerNode* node) {
2255 // We need to create a new await state which involves: 2164 // We need to create a new await state which involves:
2256 // * Increase the jump counter. Sanity check against the list of targets. 2165 // * Increase the jump counter. Sanity check against the list of targets.
2257 // * Save the current context for resuming. 2166 // * Save the current context for resuming.
2258 ASSERT(node->token_pos().IsSynthetic() || node->token_pos().IsNoSource()); 2167 ASSERT(node->token_pos().IsSynthetic() || node->token_pos().IsNoSource());
2259 ASSERT(node->async_scope() != NULL); 2168 ASSERT(node->async_scope() != NULL);
2260 ASSERT(node->await_scope() != NULL); 2169 ASSERT(node->await_scope() != NULL);
2261 LocalVariable* jump_var = node->async_scope()->LookupVariable( 2170 LocalVariable* jump_var =
2262 Symbols::AwaitJumpVar(), false); 2171 node->async_scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
2263 LocalVariable* ctx_var = node->async_scope()->LookupVariable( 2172 LocalVariable* ctx_var =
2264 Symbols::AwaitContextVar(), false); 2173 node->async_scope()->LookupVariable(Symbols::AwaitContextVar(), false);
2265 ASSERT((jump_var != NULL) && jump_var->is_captured()); 2174 ASSERT((jump_var != NULL) && jump_var->is_captured());
2266 ASSERT((ctx_var != NULL) && ctx_var->is_captured()); 2175 ASSERT((ctx_var != NULL) && ctx_var->is_captured());
2267 const intptr_t jump_count = owner()->next_await_counter(); 2176 const intptr_t jump_count = owner()->next_await_counter();
2268 ASSERT(jump_count >= 0); 2177 ASSERT(jump_count >= 0);
2269 // Sanity check that we always add a JoinEntryInstr before adding a new 2178 // Sanity check that we always add a JoinEntryInstr before adding a new
2270 // state. 2179 // state.
2271 ASSERT(jump_count == owner()->await_joins()->length()); 2180 ASSERT(jump_count == owner()->await_joins()->length());
2272 // Store the counter in :await_jump_var. 2181 // Store the counter in :await_jump_var.
2273 Value* jump_val = Bind(new(Z) ConstantInstr( 2182 Value* jump_val = Bind(new (Z) ConstantInstr(
2274 Smi::ZoneHandle(Z, Smi::New(jump_count)), node->token_pos())); 2183 Smi::ZoneHandle(Z, Smi::New(jump_count)), node->token_pos()));
2275 Do(BuildStoreLocal(*jump_var, jump_val, node->token_pos())); 2184 Do(BuildStoreLocal(*jump_var, jump_val, node->token_pos()));
2276 // Save the current context for resuming. 2185 // Save the current context for resuming.
2277 BuildSaveContext(*ctx_var, node->token_pos()); 2186 BuildSaveContext(*ctx_var, node->token_pos());
2278 } 2187 }
2279 2188
2280 2189
2281 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { 2190 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const {
2282 return kFirstLocalSlotFromFp 2191 return kFirstLocalSlotFromFp - owner()->num_stack_locals() -
2283 - owner()->num_stack_locals() 2192 owner()->num_copied_params() - owner()->args_pushed() -
2284 - owner()->num_copied_params() 2193 owner()->temp_count() + 1;
2285 - owner()->args_pushed()
2286 - owner()->temp_count() + 1;
2287 } 2194 }
2288 2195
2289 2196
2290 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) { 2197 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) {
2291 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1)); 2198 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1));
2292 intptr_t index = GetCurrentTempLocalIndex(); 2199 intptr_t index = GetCurrentTempLocalIndex();
2293 char name[64]; 2200 char name[64];
2294 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); 2201 OS::SNPrint(name, 64, ":tmp_local%" Pd, index);
2295 LocalVariable* var = 2202 LocalVariable* var =
2296 new(Z) LocalVariable(TokenPosition::kNoSource, 2203 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
2297 TokenPosition::kNoSource, 2204 String::ZoneHandle(Z, Symbols::New(T, name)),
2298 String::ZoneHandle(Z, Symbols::New(T, name)), 2205 *value->Type()->ToAbstractType());
2299 *value->Type()->ToAbstractType());
2300 var->set_index(index); 2206 var->set_index(index);
2301 return var; 2207 return var;
2302 } 2208 }
2303 2209
2304 2210
2305 Definition* EffectGraphVisitor::ExitTempLocalScope(Value* value) { 2211 Definition* EffectGraphVisitor::ExitTempLocalScope(Value* value) {
2306 return new(Z) DropTempsInstr(0, value); 2212 return new (Z) DropTempsInstr(0, value);
2307 } 2213 }
2308 2214
2309 2215
2310 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { 2216 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) {
2311 intptr_t num_temps = node->num_temps(); 2217 intptr_t num_temps = node->num_temps();
2312 for (intptr_t i = 0; i < num_temps; ++i) { 2218 for (intptr_t i = 0; i < num_temps; ++i) {
2313 ValueGraphVisitor for_value(owner()); 2219 ValueGraphVisitor for_value(owner());
2314 node->InitializerAt(i)->Visit(&for_value); 2220 node->InitializerAt(i)->Visit(&for_value);
2315 Append(for_value); 2221 Append(for_value);
2316 ASSERT(!node->TempAt(i)->HasIndex() || 2222 ASSERT(!node->TempAt(i)->HasIndex() ||
2317 (node->TempAt(i)->index() == GetCurrentTempLocalIndex())); 2223 (node->TempAt(i)->index() == GetCurrentTempLocalIndex()));
2318 node->TempAt(i)->set_index(GetCurrentTempLocalIndex()); 2224 node->TempAt(i)->set_index(GetCurrentTempLocalIndex());
2319 } 2225 }
2320 } 2226 }
2321 2227
2322 2228
2323 void EffectGraphVisitor::VisitLetNode(LetNode* node) { 2229 void EffectGraphVisitor::VisitLetNode(LetNode* node) {
2324 BuildLetTempExpressions(node); 2230 BuildLetTempExpressions(node);
2325 2231
2326 // Visit body. 2232 // Visit body.
2327 for (intptr_t i = 0; i < node->nodes().length(); ++i) { 2233 for (intptr_t i = 0; i < node->nodes().length(); ++i) {
2328 EffectGraphVisitor for_effect(owner()); 2234 EffectGraphVisitor for_effect(owner());
2329 node->nodes()[i]->Visit(&for_effect); 2235 node->nodes()[i]->Visit(&for_effect);
2330 Append(for_effect); 2236 Append(for_effect);
2331 } 2237 }
2332 2238
2333 intptr_t num_temps = node->num_temps(); 2239 intptr_t num_temps = node->num_temps();
2334 if (num_temps > 0) { 2240 if (num_temps > 0) {
2335 owner()->DeallocateTemps(num_temps); 2241 owner()->DeallocateTemps(num_temps);
2336 Do(new(Z) DropTempsInstr(num_temps, NULL)); 2242 Do(new (Z) DropTempsInstr(num_temps, NULL));
2337 } 2243 }
2338 } 2244 }
2339 2245
2340 2246
2341 void ValueGraphVisitor::VisitLetNode(LetNode* node) { 2247 void ValueGraphVisitor::VisitLetNode(LetNode* node) {
2342 BuildLetTempExpressions(node); 2248 BuildLetTempExpressions(node);
2343 2249
2344 // Visit body. 2250 // Visit body.
2345 for (intptr_t i = 0; i < node->nodes().length() - 1; ++i) { 2251 for (intptr_t i = 0; i < node->nodes().length() - 1; ++i) {
2346 EffectGraphVisitor for_effect(owner()); 2252 EffectGraphVisitor for_effect(owner());
2347 node->nodes()[i]->Visit(&for_effect); 2253 node->nodes()[i]->Visit(&for_effect);
2348 Append(for_effect); 2254 Append(for_effect);
2349 } 2255 }
2350 // Visit the last body expression for value. 2256 // Visit the last body expression for value.
2351 ValueGraphVisitor for_value(owner()); 2257 ValueGraphVisitor for_value(owner());
2352 node->nodes().Last()->Visit(&for_value); 2258 node->nodes().Last()->Visit(&for_value);
2353 Append(for_value); 2259 Append(for_value);
2354 Value* result_value = for_value.value(); 2260 Value* result_value = for_value.value();
2355 2261
2356 intptr_t num_temps = node->num_temps(); 2262 intptr_t num_temps = node->num_temps();
2357 if (num_temps > 0) { 2263 if (num_temps > 0) {
2358 owner()->DeallocateTemps(num_temps); 2264 owner()->DeallocateTemps(num_temps);
2359 ReturnDefinition(new(Z) DropTempsInstr(num_temps, result_value)); 2265 ReturnDefinition(new (Z) DropTempsInstr(num_temps, result_value));
2360 } else { 2266 } else {
2361 ReturnValue(result_value); 2267 ReturnValue(result_value);
2362 } 2268 }
2363 } 2269 }
2364 2270
2365 2271
2366 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { 2272 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
2367 const TypeArguments& type_args = 2273 const TypeArguments& type_args =
2368 TypeArguments::ZoneHandle(Z, node->type().arguments()); 2274 TypeArguments::ZoneHandle(Z, node->type().arguments());
2369 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), 2275 Value* element_type =
2370 type_args); 2276 BuildInstantiatedTypeArguments(node->token_pos(), type_args);
2371 Value* num_elements = 2277 Value* num_elements =
2372 Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(node->length())))); 2278 Bind(new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(node->length()))));
2373 CreateArrayInstr* create = new(Z) CreateArrayInstr(node->token_pos(), 2279 CreateArrayInstr* create =
2374 element_type, 2280 new (Z) CreateArrayInstr(node->token_pos(), element_type, num_elements);
2375 num_elements);
2376 Value* array_val = Bind(create); 2281 Value* array_val = Bind(create);
2377 2282
2378 { LocalVariable* tmp_var = EnterTempLocalScope(array_val); 2283 {
2284 LocalVariable* tmp_var = EnterTempLocalScope(array_val);
2379 const intptr_t class_id = kArrayCid; 2285 const intptr_t class_id = kArrayCid;
2380 const intptr_t deopt_id = Thread::kNoDeoptId; 2286 const intptr_t deopt_id = Thread::kNoDeoptId;
2381 for (int i = 0; i < node->length(); ++i) { 2287 for (int i = 0; i < node->length(); ++i) {
2382 Value* array = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); 2288 Value* array = Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos()));
2383 Value* index = 2289 Value* index = Bind(new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(i)),
2384 Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(i)), 2290 node->token_pos()));
2385 node->token_pos()));
2386 ValueGraphVisitor for_value(owner()); 2291 ValueGraphVisitor for_value(owner());
2387 node->ElementAt(i)->Visit(&for_value); 2292 node->ElementAt(i)->Visit(&for_value);
2388 Append(for_value); 2293 Append(for_value);
2389 // No store barrier needed for constants. 2294 // No store barrier needed for constants.
2390 const StoreBarrierType emit_store_barrier = 2295 const StoreBarrierType emit_store_barrier =
2391 for_value.value()->BindsToConstant() 2296 for_value.value()->BindsToConstant() ? kNoStoreBarrier
2392 ? kNoStoreBarrier 2297 : kEmitStoreBarrier;
2393 : kEmitStoreBarrier;
2394 const intptr_t index_scale = Instance::ElementSizeFor(class_id); 2298 const intptr_t index_scale = Instance::ElementSizeFor(class_id);
2395 StoreIndexedInstr* store = new(Z) StoreIndexedInstr( 2299 StoreIndexedInstr* store = new (Z) StoreIndexedInstr(
2396 array, index, for_value.value(), emit_store_barrier, 2300 array, index, for_value.value(), emit_store_barrier, index_scale,
2397 index_scale, class_id, kAlignedAccess, deopt_id, node->token_pos()); 2301 class_id, kAlignedAccess, deopt_id, node->token_pos());
2398 Do(store); 2302 Do(store);
2399 } 2303 }
2400 ReturnDefinition(ExitTempLocalScope(array_val)); 2304 ReturnDefinition(ExitTempLocalScope(array_val));
2401 } 2305 }
2402 } 2306 }
2403 2307
2404 2308
2405 void EffectGraphVisitor::VisitStringInterpolateNode( 2309 void EffectGraphVisitor::VisitStringInterpolateNode(
2406 StringInterpolateNode* node) { 2310 StringInterpolateNode* node) {
2407 ValueGraphVisitor for_argument(owner()); 2311 ValueGraphVisitor for_argument(owner());
2408 ArrayNode* arguments = node->value(); 2312 ArrayNode* arguments = node->value();
2409 if (arguments->length() == 1) { 2313 if (arguments->length() == 1) {
2410 ZoneGrowableArray<PushArgumentInstr*>* values = 2314 ZoneGrowableArray<PushArgumentInstr*>* values =
2411 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); 2315 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1);
2412 arguments->ElementAt(0)->Visit(&for_argument); 2316 arguments->ElementAt(0)->Visit(&for_argument);
2413 Append(for_argument); 2317 Append(for_argument);
2414 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); 2318 PushArgumentInstr* push_arg = PushArgument(for_argument.value());
2415 values->Add(push_arg); 2319 values->Add(push_arg);
2416 const int kNumberOfArguments = 1; 2320 const int kNumberOfArguments = 1;
2417 const Array& kNoArgumentNames = Object::null_array(); 2321 const Array& kNoArgumentNames = Object::null_array();
2418 const Class& cls = 2322 const Class& cls =
2419 Class::Handle(Library::LookupCoreClass(Symbols::StringBase())); 2323 Class::Handle(Library::LookupCoreClass(Symbols::StringBase()));
2420 ASSERT(!cls.IsNull()); 2324 ASSERT(!cls.IsNull());
2421 const Function& function = Function::ZoneHandle( 2325 const Function& function = Function::ZoneHandle(
2422 Z, 2326 Z, Resolver::ResolveStatic(
2423 Resolver::ResolveStatic( 2327 cls, Library::PrivateCoreLibName(Symbols::InterpolateSingle()),
2424 cls, 2328 kNumberOfArguments, kNoArgumentNames));
2425 Library::PrivateCoreLibName(Symbols::InterpolateSingle()),
2426 kNumberOfArguments,
2427 kNoArgumentNames));
2428 StaticCallInstr* call = 2329 StaticCallInstr* call =
2429 new(Z) StaticCallInstr(node->token_pos(), 2330 new (Z) StaticCallInstr(node->token_pos(), function, kNoArgumentNames,
2430 function, 2331 values, owner()->ic_data_array());
2431 kNoArgumentNames,
2432 values,
2433 owner()->ic_data_array());
2434 ReturnDefinition(call); 2332 ReturnDefinition(call);
2435 return; 2333 return;
2436 } 2334 }
2437 arguments->Visit(&for_argument); 2335 arguments->Visit(&for_argument);
2438 Append(for_argument); 2336 Append(for_argument);
2439 StringInterpolateInstr* instr = 2337 StringInterpolateInstr* instr =
2440 new(Z) StringInterpolateInstr(for_argument.value(), node->token_pos()); 2338 new (Z) StringInterpolateInstr(for_argument.value(), node->token_pos());
2441 ReturnDefinition(instr); 2339 ReturnDefinition(instr);
2442 } 2340 }
2443 2341
2444 2342
2445 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { 2343 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
2446 const Function& function = node->function(); 2344 const Function& function = node->function();
2447 if (function.IsImplicitStaticClosureFunction()) { 2345 if (function.IsImplicitStaticClosureFunction()) {
2448 const Instance& closure = 2346 const Instance& closure =
2449 Instance::ZoneHandle(Z, function.ImplicitStaticClosure()); 2347 Instance::ZoneHandle(Z, function.ImplicitStaticClosure());
2450 ReturnDefinition(new(Z) ConstantInstr(closure)); 2348 ReturnDefinition(new (Z) ConstantInstr(closure));
2451 return; 2349 return;
2452 } 2350 }
2453 2351
2454 const bool is_implicit = function.IsImplicitInstanceClosureFunction(); 2352 const bool is_implicit = function.IsImplicitInstanceClosureFunction();
2455 ASSERT(is_implicit || function.IsNonImplicitClosureFunction()); 2353 ASSERT(is_implicit || function.IsNonImplicitClosureFunction());
2456 // The context scope may have already been set by the non-optimizing 2354 // The context scope may have already been set by the non-optimizing
2457 // compiler. If it was not, set it here. 2355 // compiler. If it was not, set it here.
2458 if (function.context_scope() == ContextScope::null()) { 2356 if (function.context_scope() == ContextScope::null()) {
2459 ASSERT(!is_implicit); 2357 ASSERT(!is_implicit);
2460 ASSERT(node->scope() != NULL); 2358 ASSERT(node->scope() != NULL);
2461 const ContextScope& context_scope = ContextScope::ZoneHandle( 2359 const ContextScope& context_scope = ContextScope::ZoneHandle(
2462 Z, node->scope()->PreserveOuterScope(owner()->context_level())); 2360 Z, node->scope()->PreserveOuterScope(owner()->context_level()));
2463 ASSERT(!function.HasCode()); 2361 ASSERT(!function.HasCode());
2464 ASSERT(function.context_scope() == ContextScope::null()); 2362 ASSERT(function.context_scope() == ContextScope::null());
2465 function.set_context_scope(context_scope); 2363 function.set_context_scope(context_scope);
2466 2364
2467 // The closure is now properly setup, add it to the lookup table. 2365 // The closure is now properly setup, add it to the lookup table.
2468 // It is possible that the compiler creates more than one function 2366 // It is possible that the compiler creates more than one function
2469 // object for the same closure, e.g. when inlining nodes from 2367 // object for the same closure, e.g. when inlining nodes from
2470 // finally clauses. If we already have a function object for the 2368 // finally clauses. If we already have a function object for the
2471 // same closure, do not add a second one. We compare token position, 2369 // same closure, do not add a second one. We compare token position,
2472 // and parent function to detect duplicates. 2370 // and parent function to detect duplicates.
2473 const Function& parent = Function::Handle(function.parent_function()); 2371 const Function& parent = Function::Handle(function.parent_function());
2474 const Function& found_func = Function::Handle(Z, 2372 const Function& found_func = Function::Handle(
2475 isolate()->LookupClosureFunction(parent, function.token_pos())); 2373 Z, isolate()->LookupClosureFunction(parent, function.token_pos()));
2476 if (found_func.IsNull()) { 2374 if (found_func.IsNull()) {
2477 isolate()->AddClosureFunction(function); 2375 isolate()->AddClosureFunction(function);
2478 } 2376 }
2479 } 2377 }
2480 ASSERT(function.context_scope() != ContextScope::null()); 2378 ASSERT(function.context_scope() != ContextScope::null());
2481 2379
2482 // The function type of a closure may have type arguments. In that case, 2380 // The function type of a closure may have type arguments. In that case,
2483 // pass the type arguments of the instantiator. 2381 // pass the type arguments of the instantiator.
2484 const Class& closure_class = 2382 const Class& closure_class =
2485 Class::ZoneHandle(Z, isolate()->object_store()->closure_class()); 2383 Class::ZoneHandle(Z, isolate()->object_store()->closure_class());
2486 ZoneGrowableArray<PushArgumentInstr*>* no_arguments = 2384 ZoneGrowableArray<PushArgumentInstr*>* no_arguments =
2487 new(Z) ZoneGrowableArray<PushArgumentInstr*>(0); 2385 new (Z) ZoneGrowableArray<PushArgumentInstr*>(0);
2488 AllocateObjectInstr* alloc = new(Z) AllocateObjectInstr(node->token_pos(), 2386 AllocateObjectInstr* alloc = new (Z)
2489 closure_class, 2387 AllocateObjectInstr(node->token_pos(), closure_class, no_arguments);
2490 no_arguments);
2491 alloc->set_closure_function(function); 2388 alloc->set_closure_function(function);
2492 2389
2493 Value* closure_val = Bind(alloc); 2390 Value* closure_val = Bind(alloc);
2494 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val); 2391 {
2392 LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val);
2495 // Store type arguments if scope class is generic. 2393 // Store type arguments if scope class is generic.
2496 const Type& function_type = Type::ZoneHandle(Z, function.SignatureType()); 2394 const Type& function_type = Type::ZoneHandle(Z, function.SignatureType());
2497 const Class& scope_cls = Class::ZoneHandle(Z, function_type.type_class()); 2395 const Class& scope_cls = Class::ZoneHandle(Z, function_type.type_class());
2498 if (scope_cls.IsGeneric()) { 2396 if (scope_cls.IsGeneric()) {
2499 ASSERT(function.Owner() == scope_cls.raw()); 2397 ASSERT(function.Owner() == scope_cls.raw());
2500 Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var, 2398 Value* closure_tmp_val =
2501 node->token_pos())); 2399 Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos()));
2502 const Class& instantiator_class = Class::Handle( 2400 const Class& instantiator_class =
2503 Z, owner()->function().Owner()); 2401 Class::Handle(Z, owner()->function().Owner());
2504 Value* type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), 2402 Value* type_arguments = BuildInstantiatorTypeArguments(
2505 instantiator_class, 2403 node->token_pos(), instantiator_class, NULL);
2506 NULL); 2404 Do(new (Z) StoreInstanceFieldInstr(Closure::type_arguments_offset(),
2507 Do(new(Z) StoreInstanceFieldInstr(Closure::type_arguments_offset(), 2405 closure_tmp_val, type_arguments,
2508 closure_tmp_val, 2406 kEmitStoreBarrier, node->token_pos()));
2509 type_arguments,
2510 kEmitStoreBarrier,
2511 node->token_pos()));
2512 } 2407 }
2513 2408
2514 // Store function. 2409 // Store function.
2515 Value* closure_tmp_val = 2410 Value* closure_tmp_val =
2516 Bind(new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); 2411 Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos()));
2517 Value* func_val = 2412 Value* func_val =
2518 Bind(new(Z) ConstantInstr(Function::ZoneHandle(Z, function.raw()))); 2413 Bind(new (Z) ConstantInstr(Function::ZoneHandle(Z, function.raw())));
2519 Do(new(Z) StoreInstanceFieldInstr(Closure::function_offset(), 2414 Do(new (Z) StoreInstanceFieldInstr(Closure::function_offset(),
2520 closure_tmp_val, 2415 closure_tmp_val, func_val,
2521 func_val, 2416 kEmitStoreBarrier, node->token_pos()));
2522 kEmitStoreBarrier,
2523 node->token_pos()));
2524 if (is_implicit) { 2417 if (is_implicit) {
2525 // Create new context containing the receiver. 2418 // Create new context containing the receiver.
2526 const intptr_t kNumContextVariables = 1; // The receiver. 2419 const intptr_t kNumContextVariables = 1; // The receiver.
2527 Value* allocated_context = 2420 Value* allocated_context = Bind(new (Z) AllocateContextInstr(
2528 Bind(new(Z) AllocateContextInstr(node->token_pos(), 2421 node->token_pos(), kNumContextVariables));
2529 kNumContextVariables)); 2422 {
2530 { LocalVariable* context_tmp_var = EnterTempLocalScope(allocated_context); 2423 LocalVariable* context_tmp_var = EnterTempLocalScope(allocated_context);
2531 // Store receiver in context. 2424 // Store receiver in context.
2532 Value* context_tmp_val = 2425 Value* context_tmp_val =
2533 Bind(new(Z) LoadLocalInstr(*context_tmp_var, node->token_pos())); 2426 Bind(new (Z) LoadLocalInstr(*context_tmp_var, node->token_pos()));
2534 ValueGraphVisitor for_receiver(owner()); 2427 ValueGraphVisitor for_receiver(owner());
2535 node->receiver()->Visit(&for_receiver); 2428 node->receiver()->Visit(&for_receiver);
2536 Append(for_receiver); 2429 Append(for_receiver);
2537 Value* receiver = for_receiver.value(); 2430 Value* receiver = for_receiver.value();
2538 Do(new(Z) StoreInstanceFieldInstr(Context::variable_offset(0), 2431 Do(new (Z) StoreInstanceFieldInstr(
2539 context_tmp_val, 2432 Context::variable_offset(0), context_tmp_val, receiver,
2540 receiver, 2433 kEmitStoreBarrier, node->token_pos()));
2541 kEmitStoreBarrier,
2542 node->token_pos()));
2543 // Store new context in closure. 2434 // Store new context in closure.
2544 closure_tmp_val = 2435 closure_tmp_val =
2545 Bind(new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); 2436 Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos()));
2546 context_tmp_val = 2437 context_tmp_val =
2547 Bind(new(Z) LoadLocalInstr(*context_tmp_var, node->token_pos())); 2438 Bind(new (Z) LoadLocalInstr(*context_tmp_var, node->token_pos()));
2548 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(), 2439 Do(new (Z) StoreInstanceFieldInstr(
2549 closure_tmp_val, 2440 Closure::context_offset(), closure_tmp_val, context_tmp_val,
2550 context_tmp_val, 2441 kEmitStoreBarrier, node->token_pos()));
2551 kEmitStoreBarrier,
2552 node->token_pos()));
2553 Do(ExitTempLocalScope(allocated_context)); 2442 Do(ExitTempLocalScope(allocated_context));
2554 } 2443 }
2555 } else { 2444 } else {
2556 // Store current context in closure. 2445 // Store current context in closure.
2557 closure_tmp_val = Bind( 2446 closure_tmp_val =
2558 new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); 2447 Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos()));
2559 Value* context = Bind(BuildCurrentContext(node->token_pos())); 2448 Value* context = Bind(BuildCurrentContext(node->token_pos()));
2560 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(), 2449 Do(new (Z) StoreInstanceFieldInstr(Closure::context_offset(),
2561 closure_tmp_val, 2450 closure_tmp_val, context,
2562 context, 2451 kEmitStoreBarrier, node->token_pos()));
2563 kEmitStoreBarrier,
2564 node->token_pos()));
2565 } 2452 }
2566 ReturnDefinition(ExitTempLocalScope(closure_val)); 2453 ReturnDefinition(ExitTempLocalScope(closure_val));
2567 } 2454 }
2568 } 2455 }
2569 2456
2570 2457
2571 void EffectGraphVisitor::BuildPushArguments( 2458 void EffectGraphVisitor::BuildPushArguments(
2572 const ArgumentListNode& node, 2459 const ArgumentListNode& node,
2573 ZoneGrowableArray<PushArgumentInstr*>* values) { 2460 ZoneGrowableArray<PushArgumentInstr*>* values) {
2574 for (intptr_t i = 0; i < node.length(); ++i) { 2461 for (intptr_t i = 0; i < node.length(); ++i) {
2575 ValueGraphVisitor for_argument(owner()); 2462 ValueGraphVisitor for_argument(owner());
2576 node.NodeAt(i)->Visit(&for_argument); 2463 node.NodeAt(i)->Visit(&for_argument);
2577 Append(for_argument); 2464 Append(for_argument);
2578 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); 2465 PushArgumentInstr* push_arg = PushArgument(for_argument.value());
2579 values->Add(push_arg); 2466 values->Add(push_arg);
2580 } 2467 }
2581 } 2468 }
2582 2469
2583 2470
2584 void EffectGraphVisitor::BuildInstanceCallConditional(InstanceCallNode* node) { 2471 void EffectGraphVisitor::BuildInstanceCallConditional(InstanceCallNode* node) {
2585 const TokenPosition token_pos = node->token_pos(); 2472 const TokenPosition token_pos = node->token_pos();
2586 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); 2473 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
2587 LoadLocalNode* load_temp = new(Z) LoadLocalNode(token_pos, temp_var); 2474 LoadLocalNode* load_temp = new (Z) LoadLocalNode(token_pos, temp_var);
2588 2475
2589 LiteralNode* null_constant = 2476 LiteralNode* null_constant =
2590 new(Z) LiteralNode(ST(token_pos), Object::null_instance()); 2477 new (Z) LiteralNode(ST(token_pos), Object::null_instance());
2591 ComparisonNode* check_is_null = 2478 ComparisonNode* check_is_null = new (Z)
2592 new(Z) ComparisonNode(ST(token_pos), 2479 ComparisonNode(ST(token_pos), Token::kEQ, load_temp, null_constant);
2593 Token::kEQ,
2594 load_temp,
2595 null_constant);
2596 TestGraphVisitor for_test(owner(), ST(token_pos)); 2480 TestGraphVisitor for_test(owner(), ST(token_pos));
2597 check_is_null->Visit(&for_test); 2481 check_is_null->Visit(&for_test);
2598 2482
2599 EffectGraphVisitor for_true(owner()); 2483 EffectGraphVisitor for_true(owner());
2600 EffectGraphVisitor for_false(owner()); 2484 EffectGraphVisitor for_false(owner());
2601 2485
2602 StoreLocalNode* store_null = 2486 StoreLocalNode* store_null =
2603 new(Z) StoreLocalNode(ST(token_pos), temp_var, null_constant); 2487 new (Z) StoreLocalNode(ST(token_pos), temp_var, null_constant);
2604 store_null->Visit(&for_true); 2488 store_null->Visit(&for_true);
2605 2489
2606 InstanceCallNode* call = 2490 InstanceCallNode* call = new (Z) InstanceCallNode(
2607 new(Z) InstanceCallNode(token_pos, 2491 token_pos, load_temp, node->function_name(), node->arguments());
2608 load_temp,
2609 node->function_name(),
2610 node->arguments());
2611 StoreLocalNode* store_result = 2492 StoreLocalNode* store_result =
2612 new(Z) StoreLocalNode(ST(token_pos), temp_var, call); 2493 new (Z) StoreLocalNode(ST(token_pos), temp_var, call);
2613 store_result->Visit(&for_false); 2494 store_result->Visit(&for_false);
2614 2495
2615 Join(for_test, for_true, for_false); 2496 Join(for_test, for_true, for_false);
2616 } 2497 }
2617 2498
2618 2499
2619 void ValueGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { 2500 void ValueGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
2620 if (node->is_conditional()) { 2501 if (node->is_conditional()) {
2621 ValueGraphVisitor for_receiver(owner()); 2502 ValueGraphVisitor for_receiver(owner());
2622 node->receiver()->Visit(&for_receiver); 2503 node->receiver()->Visit(&for_receiver);
2623 Append(for_receiver); 2504 Append(for_receiver);
2624 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos())); 2505 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos()));
2625 BuildInstanceCallConditional(node); 2506 BuildInstanceCallConditional(node);
2626 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); 2507 ReturnDefinition(BuildLoadExprTemp(node->token_pos()));
2627 } else { 2508 } else {
2628 EffectGraphVisitor::VisitInstanceCallNode(node); 2509 EffectGraphVisitor::VisitInstanceCallNode(node);
2629 } 2510 }
2630 } 2511 }
2631 2512
2632 2513
2633 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { 2514 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
2634 ValueGraphVisitor for_receiver(owner()); 2515 ValueGraphVisitor for_receiver(owner());
2635 node->receiver()->Visit(&for_receiver); 2516 node->receiver()->Visit(&for_receiver);
2636 Append(for_receiver); 2517 Append(for_receiver);
2637 if (node->is_conditional()) { 2518 if (node->is_conditional()) {
2638 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos())); 2519 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos()));
2639 BuildInstanceCallConditional(node); 2520 BuildInstanceCallConditional(node);
2640 } else { 2521 } else {
2641 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 2522 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
2642 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2523 ZoneGrowableArray<PushArgumentInstr*>* arguments = new (Z)
2643 new(Z) ZoneGrowableArray<PushArgumentInstr*>( 2524 ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length() + 1);
2644 node->arguments()->length() + 1);
2645 arguments->Add(push_receiver); 2525 arguments->Add(push_receiver);
2646 2526
2647 BuildPushArguments(*node->arguments(), arguments); 2527 BuildPushArguments(*node->arguments(), arguments);
2648 InstanceCallInstr* call = new(Z) InstanceCallInstr( 2528 InstanceCallInstr* call = new (Z) InstanceCallInstr(
2649 node->token_pos(), 2529 node->token_pos(), node->function_name(), Token::kILLEGAL, arguments,
2650 node->function_name(), 2530 node->arguments()->names(), 1, owner()->ic_data_array());
2651 Token::kILLEGAL,
2652 arguments,
2653 node->arguments()->names(),
2654 1,
2655 owner()->ic_data_array());
2656 ReturnDefinition(call); 2531 ReturnDefinition(call);
2657 } 2532 }
2658 } 2533 }
2659 2534
2660 2535
2661 // <Expression> ::= StaticCall { function: Function 2536 // <Expression> ::= StaticCall { function: Function
2662 // arguments: <ArgumentList> } 2537 // arguments: <ArgumentList> }
2663 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { 2538 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
2664 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2539 ZoneGrowableArray<PushArgumentInstr*>* arguments = new (Z)
2665 new(Z) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); 2540 ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
2666 BuildPushArguments(*node->arguments(), arguments); 2541 BuildPushArguments(*node->arguments(), arguments);
2667 StaticCallInstr* call = 2542 StaticCallInstr* call = new (Z) StaticCallInstr(
2668 new(Z) StaticCallInstr(node->token_pos(), 2543 node->token_pos(), node->function(), node->arguments()->names(),
2669 node->function(), 2544 arguments, owner()->ic_data_array());
2670 node->arguments()->names(),
2671 arguments,
2672 owner()->ic_data_array());
2673 if (node->function().recognized_kind() != MethodRecognizer::kUnknown) { 2545 if (node->function().recognized_kind() != MethodRecognizer::kUnknown) {
2674 call->set_result_cid(MethodRecognizer::ResultCid(node->function())); 2546 call->set_result_cid(MethodRecognizer::ResultCid(node->function()));
2675 } 2547 }
2676 ReturnDefinition(call); 2548 ReturnDefinition(call);
2677 } 2549 }
2678 2550
2679 2551
2680 void EffectGraphVisitor::BuildClosureCall( 2552 void EffectGraphVisitor::BuildClosureCall(ClosureCallNode* node,
2681 ClosureCallNode* node, bool result_needed) { 2553 bool result_needed) {
2682 ValueGraphVisitor for_closure(owner()); 2554 ValueGraphVisitor for_closure(owner());
2683 node->closure()->Visit(&for_closure); 2555 node->closure()->Visit(&for_closure);
2684 Append(for_closure); 2556 Append(for_closure);
2685 2557
2686 Value* closure_value = for_closure.value(); 2558 Value* closure_value = for_closure.value();
2687 LocalVariable* tmp_var = EnterTempLocalScope(closure_value); 2559 LocalVariable* tmp_var = EnterTempLocalScope(closure_value);
2688 2560
2689 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2561 ZoneGrowableArray<PushArgumentInstr*>* arguments = new (Z)
2690 new(Z) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); 2562 ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
2691 Value* closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); 2563 Value* closure_val =
2564 Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos()));
2692 PushArgumentInstr* push_closure = PushArgument(closure_val); 2565 PushArgumentInstr* push_closure = PushArgument(closure_val);
2693 arguments->Add(push_closure); 2566 arguments->Add(push_closure);
2694 BuildPushArguments(*node->arguments(), arguments); 2567 BuildPushArguments(*node->arguments(), arguments);
2695 2568
2696 closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); 2569 closure_val = Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos()));
2697 LoadFieldInstr* function_load = new(Z) LoadFieldInstr( 2570 LoadFieldInstr* function_load = new (Z) LoadFieldInstr(
2698 closure_val, 2571 closure_val, Closure::function_offset(),
2699 Closure::function_offset(), 2572 AbstractType::ZoneHandle(Z, AbstractType::null()), node->token_pos());
2700 AbstractType::ZoneHandle(Z, AbstractType::null()),
2701 node->token_pos());
2702 function_load->set_is_immutable(true); 2573 function_load->set_is_immutable(true);
2703 Value* function_val = Bind(function_load); 2574 Value* function_val = Bind(function_load);
2704 2575
2705 Definition* closure_call = 2576 Definition* closure_call =
2706 new(Z) ClosureCallInstr(function_val, node, arguments); 2577 new (Z) ClosureCallInstr(function_val, node, arguments);
2707 if (result_needed) { 2578 if (result_needed) {
2708 Value* result = Bind(closure_call); 2579 Value* result = Bind(closure_call);
2709 Do(new(Z) StoreLocalInstr(*tmp_var, result, ST(node->token_pos()))); 2580 Do(new (Z) StoreLocalInstr(*tmp_var, result, ST(node->token_pos())));
2710 } else { 2581 } else {
2711 Do(closure_call); 2582 Do(closure_call);
2712 } 2583 }
2713 ReturnDefinition(ExitTempLocalScope(closure_value)); 2584 ReturnDefinition(ExitTempLocalScope(closure_value));
2714 } 2585 }
2715 2586
2716 2587
2717 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 2588 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
2718 BuildClosureCall(node, false); 2589 BuildClosureCall(node, false);
2719 } 2590 }
2720 2591
2721 2592
2722 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 2593 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
2723 BuildClosureCall(node, true); 2594 BuildClosureCall(node, true);
2724 } 2595 }
2725 2596
2726 2597
2727 void EffectGraphVisitor::VisitInitStaticFieldNode(InitStaticFieldNode* node) { 2598 void EffectGraphVisitor::VisitInitStaticFieldNode(InitStaticFieldNode* node) {
2728 Value* field = Bind(new(Z) ConstantInstr( 2599 Value* field = Bind(
2729 Field::ZoneHandle(Z, node->field().Original()))); 2600 new (Z) ConstantInstr(Field::ZoneHandle(Z, node->field().Original())));
2730 AddInstruction(new(Z) InitStaticFieldInstr(field, node->field())); 2601 AddInstruction(new (Z) InitStaticFieldInstr(field, node->field()));
2731 } 2602 }
2732 2603
2733 2604
2734 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { 2605 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
2735 Value* context = Bind(BuildCurrentContext(node->token_pos())); 2606 Value* context = Bind(BuildCurrentContext(node->token_pos()));
2736 Value* clone = Bind(new(Z) CloneContextInstr(node->token_pos(), context)); 2607 Value* clone = Bind(new (Z) CloneContextInstr(node->token_pos(), context));
2737 Do(BuildStoreContext(clone, node->token_pos())); 2608 Do(BuildStoreContext(clone, node->token_pos()));
2738 } 2609 }
2739 2610
2740 2611
2741 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) { 2612 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) {
2742 const Class& cls = Class::ZoneHandle(Z, node->constructor().Owner()); 2613 const Class& cls = Class::ZoneHandle(Z, node->constructor().Owner());
2743 const bool cls_is_parameterized = cls.NumTypeArguments() > 0; 2614 const bool cls_is_parameterized = cls.NumTypeArguments() > 0;
2744 2615
2745 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = 2616 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = new (Z)
2746 new(Z) ZoneGrowableArray<PushArgumentInstr*>( 2617 ZoneGrowableArray<PushArgumentInstr*>(cls_is_parameterized ? 1 : 0);
2747 cls_is_parameterized ? 1 : 0);
2748 if (cls_is_parameterized) { 2618 if (cls_is_parameterized) {
2749 Value* type_args = BuildInstantiatedTypeArguments(node->token_pos(), 2619 Value* type_args = BuildInstantiatedTypeArguments(node->token_pos(),
2750 node->type_arguments()); 2620 node->type_arguments());
2751 allocate_arguments->Add(PushArgument(type_args)); 2621 allocate_arguments->Add(PushArgument(type_args));
2752 } 2622 }
2753 2623
2754 Definition* allocation = new(Z) AllocateObjectInstr( 2624 Definition* allocation = new (Z) AllocateObjectInstr(
2755 node->token_pos(), 2625 node->token_pos(), Class::ZoneHandle(Z, node->constructor().Owner()),
2756 Class::ZoneHandle(Z, node->constructor().Owner()),
2757 allocate_arguments); 2626 allocate_arguments);
2758 2627
2759 return Bind(allocation); 2628 return Bind(allocation);
2760 } 2629 }
2761 2630
2762 2631
2763 void EffectGraphVisitor::BuildConstructorCall( 2632 void EffectGraphVisitor::BuildConstructorCall(
2764 ConstructorCallNode* node, 2633 ConstructorCallNode* node,
2765 PushArgumentInstr* push_alloc_value) { 2634 PushArgumentInstr* push_alloc_value) {
2766
2767 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2635 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2768 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); 2636 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
2769 arguments->Add(push_alloc_value); 2637 arguments->Add(push_alloc_value);
2770 2638
2771 BuildPushArguments(*node->arguments(), arguments); 2639 BuildPushArguments(*node->arguments(), arguments);
2772 Do(new(Z) StaticCallInstr(node->token_pos(), 2640 Do(new (Z) StaticCallInstr(node->token_pos(), node->constructor(),
2773 node->constructor(), 2641 node->arguments()->names(), arguments,
2774 node->arguments()->names(), 2642 owner()->ic_data_array()));
2775 arguments,
2776 owner()->ic_data_array()));
2777 } 2643 }
2778 2644
2779 2645
2780 static intptr_t GetResultCidOfListFactory(ConstructorCallNode* node) { 2646 static intptr_t GetResultCidOfListFactory(ConstructorCallNode* node) {
2781 const Function& function = node->constructor(); 2647 const Function& function = node->constructor();
2782 const Class& function_class = Class::Handle(function.Owner()); 2648 const Class& function_class = Class::Handle(function.Owner());
2783 2649
2784 if ((function_class.library() != Library::CoreLibrary()) && 2650 if ((function_class.library() != Library::CoreLibrary()) &&
2785 (function_class.library() != Library::TypedDataLibrary())) { 2651 (function_class.library() != Library::TypedDataLibrary())) {
2786 return kDynamicCid; 2652 return kDynamicCid;
2787 } 2653 }
2788 2654
2789 if (node->constructor().IsFactory()) { 2655 if (node->constructor().IsFactory()) {
2790 if ((function_class.Name() == Symbols::List().raw()) && 2656 if ((function_class.Name() == Symbols::List().raw()) &&
2791 (function.name() == Symbols::ListFactory().raw())) { 2657 (function.name() == Symbols::ListFactory().raw())) {
2792 // Special recognition of 'new List()' vs 'new List(n)'. 2658 // Special recognition of 'new List()' vs 'new List(n)'.
2793 if (node->arguments()->length() == 0) { 2659 if (node->arguments()->length() == 0) {
2794 return kGrowableObjectArrayCid; 2660 return kGrowableObjectArrayCid;
2795 } 2661 }
2796 return kArrayCid; 2662 return kArrayCid;
2797 } 2663 }
2798 return FactoryRecognizer::ResultCid(function); 2664 return FactoryRecognizer::ResultCid(function);
2799 } 2665 }
2800 return kDynamicCid; // Not a known list constructor. 2666 return kDynamicCid; // Not a known list constructor.
2801 } 2667 }
2802 2668
2803 2669
2804 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 2670 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
2805 if (node->constructor().IsFactory()) { 2671 if (node->constructor().IsFactory()) {
2806 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2672 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2807 new(Z) ZoneGrowableArray<PushArgumentInstr*>(); 2673 new (Z) ZoneGrowableArray<PushArgumentInstr*>();
2808 PushArgumentInstr* push_type_arguments = PushArgument( 2674 PushArgumentInstr* push_type_arguments =
2809 BuildInstantiatedTypeArguments(node->token_pos(), 2675 PushArgument(BuildInstantiatedTypeArguments(node->token_pos(),
2810 node->type_arguments())); 2676 node->type_arguments()));
2811 arguments->Add(push_type_arguments); 2677 arguments->Add(push_type_arguments);
2812 ASSERT(arguments->length() == 1); 2678 ASSERT(arguments->length() == 1);
2813 BuildPushArguments(*node->arguments(), arguments); 2679 BuildPushArguments(*node->arguments(), arguments);
2814 StaticCallInstr* call = 2680 StaticCallInstr* call = new (Z) StaticCallInstr(
2815 new(Z) StaticCallInstr(node->token_pos(), 2681 node->token_pos(), node->constructor(), node->arguments()->names(),
2816 node->constructor(), 2682 arguments, owner()->ic_data_array());
2817 node->arguments()->names(),
2818 arguments,
2819 owner()->ic_data_array());
2820 const intptr_t result_cid = GetResultCidOfListFactory(node); 2683 const intptr_t result_cid = GetResultCidOfListFactory(node);
2821 if (result_cid != kDynamicCid) { 2684 if (result_cid != kDynamicCid) {
2822 call->set_result_cid(result_cid); 2685 call->set_result_cid(result_cid);
2823 call->set_is_known_list_constructor(true); 2686 call->set_is_known_list_constructor(true);
2824 // Recognized fixed length array factory must have two arguments: 2687 // Recognized fixed length array factory must have two arguments:
2825 // (0) type-arguments, (1) length. 2688 // (0) type-arguments, (1) length.
2826 ASSERT(!LoadFieldInstr::IsFixedLengthArrayCid(result_cid) || 2689 ASSERT(!LoadFieldInstr::IsFixedLengthArrayCid(result_cid) ||
2827 arguments->length() == 2); 2690 arguments->length() == 2);
2828 } else if (node->constructor().recognized_kind() != 2691 } else if (node->constructor().recognized_kind() !=
2829 MethodRecognizer::kUnknown) { 2692 MethodRecognizer::kUnknown) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2864 // is not NULL. 2727 // is not NULL.
2865 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( 2728 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments(
2866 TokenPosition token_pos, 2729 TokenPosition token_pos,
2867 const Class& instantiator_class, 2730 const Class& instantiator_class,
2868 Value* instantiator) { 2731 Value* instantiator) {
2869 if (!instantiator_class.IsGeneric()) { 2732 if (!instantiator_class.IsGeneric()) {
2870 // The type arguments are compile time constants. 2733 // The type arguments are compile time constants.
2871 TypeArguments& type_arguments = 2734 TypeArguments& type_arguments =
2872 TypeArguments::ZoneHandle(Z, TypeArguments::null()); 2735 TypeArguments::ZoneHandle(Z, TypeArguments::null());
2873 // Type is temporary. Only its type arguments are preserved. 2736 // Type is temporary. Only its type arguments are preserved.
2874 Type& type = Type::Handle( 2737 Type& type = Type::Handle(Z, Type::New(instantiator_class, type_arguments,
2875 Z, 2738 token_pos, Heap::kNew));
2876 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); 2739 type ^= ClassFinalizer::FinalizeType(instantiator_class, type,
2877 type ^= ClassFinalizer::FinalizeType( 2740 ClassFinalizer::kFinalize);
2878 instantiator_class, type, ClassFinalizer::kFinalize);
2879 ASSERT(!type.IsMalformedOrMalbounded()); 2741 ASSERT(!type.IsMalformedOrMalbounded());
2880 type_arguments = type.arguments(); 2742 type_arguments = type.arguments();
2881 type_arguments = type_arguments.Canonicalize(); 2743 type_arguments = type_arguments.Canonicalize();
2882 return Bind(new(Z) ConstantInstr(type_arguments)); 2744 return Bind(new (Z) ConstantInstr(type_arguments));
2883 } 2745 }
2884 Function& outer_function = Function::Handle(Z, owner()->function().raw()); 2746 Function& outer_function = Function::Handle(Z, owner()->function().raw());
2885 while (outer_function.IsLocalFunction()) { 2747 while (outer_function.IsLocalFunction()) {
2886 outer_function = outer_function.parent_function(); 2748 outer_function = outer_function.parent_function();
2887 } 2749 }
2888 if (outer_function.IsFactory()) { 2750 if (outer_function.IsFactory()) {
2889 // No instantiator for factories. 2751 // No instantiator for factories.
2890 ASSERT(instantiator == NULL); 2752 ASSERT(instantiator == NULL);
2891 LocalVariable* instantiator_var = 2753 LocalVariable* instantiator_var = owner()->parsed_function().instantiator();
2892 owner()->parsed_function().instantiator();
2893 ASSERT(instantiator_var != NULL); 2754 ASSERT(instantiator_var != NULL);
2894 return Bind(BuildLoadLocal(*instantiator_var, token_pos)); 2755 return Bind(BuildLoadLocal(*instantiator_var, token_pos));
2895 } 2756 }
2896 if (instantiator == NULL) { 2757 if (instantiator == NULL) {
2897 instantiator = BuildInstantiator(token_pos); 2758 instantiator = BuildInstantiator(token_pos);
2898 } 2759 }
2899 // The instantiator is the receiver of the caller, which is not a factory. 2760 // The instantiator is the receiver of the caller, which is not a factory.
2900 // The receiver cannot be null; extract its TypeArguments object. 2761 // The receiver cannot be null; extract its TypeArguments object.
2901 // Note that in the factory case, the instantiator is the first parameter 2762 // Note that in the factory case, the instantiator is the first parameter
2902 // of the factory, i.e. already a TypeArguments object. 2763 // of the factory, i.e. already a TypeArguments object.
2903 intptr_t type_arguments_field_offset = 2764 intptr_t type_arguments_field_offset =
2904 instantiator_class.type_arguments_field_offset(); 2765 instantiator_class.type_arguments_field_offset();
2905 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); 2766 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments);
2906 2767
2907 return Bind(new(Z) LoadFieldInstr( 2768 return Bind(new (Z) LoadFieldInstr(
2908 instantiator, 2769 instantiator, type_arguments_field_offset,
2909 type_arguments_field_offset,
2910 Type::ZoneHandle(Z, Type::null()), // Not an instance, no type. 2770 Type::ZoneHandle(Z, Type::null()), // Not an instance, no type.
2911 token_pos)); 2771 token_pos));
2912 } 2772 }
2913 2773
2914 2774
2915 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( 2775 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments(
2916 TokenPosition token_pos, 2776 TokenPosition token_pos,
2917 const TypeArguments& type_arguments) { 2777 const TypeArguments& type_arguments) {
2918 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { 2778 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
2919 return Bind(new(Z) ConstantInstr(type_arguments)); 2779 return Bind(new (Z) ConstantInstr(type_arguments));
2920 } 2780 }
2921 // The type arguments are uninstantiated. 2781 // The type arguments are uninstantiated.
2922 const Class& instantiator_class = Class::ZoneHandle( 2782 const Class& instantiator_class =
2923 Z, owner()->function().Owner()); 2783 Class::ZoneHandle(Z, owner()->function().Owner());
2924 Value* instantiator_value = 2784 Value* instantiator_value =
2925 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 2785 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
2926 const bool use_instantiator_type_args = 2786 const bool use_instantiator_type_args =
2927 type_arguments.IsUninstantiatedIdentity() || 2787 type_arguments.IsUninstantiatedIdentity() ||
2928 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class); 2788 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class);
2929 if (use_instantiator_type_args) { 2789 if (use_instantiator_type_args) {
2930 return instantiator_value; 2790 return instantiator_value;
2931 } else { 2791 } else {
2932 return Bind(new(Z) InstantiateTypeArgumentsInstr(token_pos, 2792 return Bind(new (Z) InstantiateTypeArgumentsInstr(
2933 type_arguments, 2793 token_pos, type_arguments, instantiator_class, instantiator_value));
2934 instantiator_class,
2935 instantiator_value));
2936 } 2794 }
2937 } 2795 }
2938 2796
2939 2797
2940 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 2798 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
2941 if (node->constructor().IsFactory()) { 2799 if (node->constructor().IsFactory()) {
2942 EffectGraphVisitor::VisitConstructorCallNode(node); 2800 EffectGraphVisitor::VisitConstructorCallNode(node);
2943 return; 2801 return;
2944 } 2802 }
2945 2803
2946 // t_n contains the allocated and initialized object. 2804 // t_n contains the allocated and initialized object.
2947 // t_n <- AllocateObject(class) 2805 // t_n <- AllocateObject(class)
2948 // t_n <- StoreLocal(temp, t_n); 2806 // t_n <- StoreLocal(temp, t_n);
2949 // t_n+1 <- ctor-arg 2807 // t_n+1 <- ctor-arg
2950 // t_n+2... <- constructor arguments start here 2808 // t_n+2... <- constructor arguments start here
2951 // StaticCall(constructor, t_n, t_n+1, ...) 2809 // StaticCall(constructor, t_n, t_n+1, ...)
2952 // tn <- LoadLocal(temp) 2810 // tn <- LoadLocal(temp)
2953 2811
2954 Value* allocate = BuildObjectAllocation(node); 2812 Value* allocate = BuildObjectAllocation(node);
2955 { LocalVariable* tmp_var = EnterTempLocalScope(allocate); 2813 {
2814 LocalVariable* tmp_var = EnterTempLocalScope(allocate);
2956 Value* allocated_tmp = 2815 Value* allocated_tmp =
2957 Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); 2816 Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos()));
2958 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); 2817 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp);
2959 BuildConstructorCall(node, push_allocated_value); 2818 BuildConstructorCall(node, push_allocated_value);
2960 ReturnDefinition(ExitTempLocalScope(allocate)); 2819 ReturnDefinition(ExitTempLocalScope(allocate));
2961 } 2820 }
2962 } 2821 }
2963 2822
2964 2823
2965
2966 void EffectGraphVisitor::BuildInstanceGetterConditional( 2824 void EffectGraphVisitor::BuildInstanceGetterConditional(
2967 InstanceGetterNode* node) { 2825 InstanceGetterNode* node) {
2968 const TokenPosition token_pos = node->token_pos(); 2826 const TokenPosition token_pos = node->token_pos();
2969 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); 2827 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
2970 LoadLocalNode* load_temp = new(Z) LoadLocalNode(token_pos, temp_var); 2828 LoadLocalNode* load_temp = new (Z) LoadLocalNode(token_pos, temp_var);
2971 2829
2972 LiteralNode* null_constant = 2830 LiteralNode* null_constant =
2973 new(Z) LiteralNode(ST(token_pos), Object::null_instance()); 2831 new (Z) LiteralNode(ST(token_pos), Object::null_instance());
2974 ComparisonNode* check_is_null = 2832 ComparisonNode* check_is_null = new (Z)
2975 new(Z) ComparisonNode(ST(token_pos), 2833 ComparisonNode(ST(token_pos), Token::kEQ, load_temp, null_constant);
2976 Token::kEQ,
2977 load_temp,
2978 null_constant);
2979 TestGraphVisitor for_test(owner(), ST(token_pos)); 2834 TestGraphVisitor for_test(owner(), ST(token_pos));
2980 check_is_null->Visit(&for_test); 2835 check_is_null->Visit(&for_test);
2981 2836
2982 EffectGraphVisitor for_true(owner()); 2837 EffectGraphVisitor for_true(owner());
2983 EffectGraphVisitor for_false(owner()); 2838 EffectGraphVisitor for_false(owner());
2984 2839
2985 StoreLocalNode* store_null = 2840 StoreLocalNode* store_null =
2986 new(Z) StoreLocalNode(ST(token_pos), temp_var, null_constant); 2841 new (Z) StoreLocalNode(ST(token_pos), temp_var, null_constant);
2987 store_null->Visit(&for_true); 2842 store_null->Visit(&for_true);
2988 2843
2989 InstanceGetterNode* getter = new(Z) InstanceGetterNode(token_pos, 2844 InstanceGetterNode* getter =
2990 load_temp, 2845 new (Z) InstanceGetterNode(token_pos, load_temp, node->field_name());
2991 node->field_name());
2992 StoreLocalNode* store_getter = 2846 StoreLocalNode* store_getter =
2993 new(Z) StoreLocalNode(ST(token_pos), temp_var, getter); 2847 new (Z) StoreLocalNode(ST(token_pos), temp_var, getter);
2994 store_getter->Visit(&for_false); 2848 store_getter->Visit(&for_false);
2995 2849
2996 Join(for_test, for_true, for_false); 2850 Join(for_test, for_true, for_false);
2997 } 2851 }
2998 2852
2999 2853
3000 void ValueGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { 2854 void ValueGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
3001 if (node->is_conditional()) { 2855 if (node->is_conditional()) {
3002 ValueGraphVisitor for_receiver(owner()); 2856 ValueGraphVisitor for_receiver(owner());
3003 node->receiver()->Visit(&for_receiver); 2857 node->receiver()->Visit(&for_receiver);
(...skipping 10 matching lines...) Expand all
3014 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { 2868 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
3015 ValueGraphVisitor for_receiver(owner()); 2869 ValueGraphVisitor for_receiver(owner());
3016 node->receiver()->Visit(&for_receiver); 2870 node->receiver()->Visit(&for_receiver);
3017 Append(for_receiver); 2871 Append(for_receiver);
3018 if (node->is_conditional()) { 2872 if (node->is_conditional()) {
3019 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos())); 2873 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos()));
3020 BuildInstanceGetterConditional(node); 2874 BuildInstanceGetterConditional(node);
3021 } else { 2875 } else {
3022 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 2876 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
3023 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2877 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3024 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); 2878 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1);
3025 arguments->Add(push_receiver); 2879 arguments->Add(push_receiver);
3026 const String& name = 2880 const String& name =
3027 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name())); 2881 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name()));
3028 InstanceCallInstr* call = new(Z) InstanceCallInstr( 2882 InstanceCallInstr* call = new (Z)
3029 node->token_pos(), 2883 InstanceCallInstr(node->token_pos(), name, Token::kGET, arguments,
3030 name, 2884 Object::null_array(), 1, owner()->ic_data_array());
3031 Token::kGET,
3032 arguments, Object::null_array(),
3033 1,
3034 owner()->ic_data_array());
3035 ReturnDefinition(call); 2885 ReturnDefinition(call);
3036 } 2886 }
3037 } 2887 }
3038 2888
3039 2889
3040 void EffectGraphVisitor::BuildInstanceSetterArguments( 2890 void EffectGraphVisitor::BuildInstanceSetterArguments(
3041 InstanceSetterNode* node, 2891 InstanceSetterNode* node,
3042 ZoneGrowableArray<PushArgumentInstr*>* arguments, 2892 ZoneGrowableArray<PushArgumentInstr*>* arguments,
3043 bool result_is_needed) { 2893 bool result_is_needed) {
3044 ValueGraphVisitor for_receiver(owner()); 2894 ValueGraphVisitor for_receiver(owner());
(...skipping 17 matching lines...) Expand all
3062 2912
3063 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 2913 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
3064 const TokenPosition token_pos = node->token_pos(); 2914 const TokenPosition token_pos = node->token_pos();
3065 if (node->is_conditional()) { 2915 if (node->is_conditional()) {
3066 ValueGraphVisitor for_receiver(owner()); 2916 ValueGraphVisitor for_receiver(owner());
3067 node->receiver()->Visit(&for_receiver); 2917 node->receiver()->Visit(&for_receiver);
3068 Append(for_receiver); 2918 Append(for_receiver);
3069 Do(BuildStoreExprTemp(for_receiver.value(), token_pos)); 2919 Do(BuildStoreExprTemp(for_receiver.value(), token_pos));
3070 2920
3071 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); 2921 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
3072 LoadLocalNode* load_temp = 2922 LoadLocalNode* load_temp = new (Z) LoadLocalNode(ST(token_pos), temp_var);
3073 new(Z) LoadLocalNode(ST(token_pos), temp_var);
3074 LiteralNode* null_constant = 2923 LiteralNode* null_constant =
3075 new(Z) LiteralNode(ST(token_pos), Object::null_instance()); 2924 new (Z) LiteralNode(ST(token_pos), Object::null_instance());
3076 ComparisonNode* check_is_null = 2925 ComparisonNode* check_is_null = new (Z)
3077 new(Z) ComparisonNode(ST(token_pos), 2926 ComparisonNode(ST(token_pos), Token::kEQ, load_temp, null_constant);
3078 Token::kEQ,
3079 load_temp,
3080 null_constant);
3081 TestGraphVisitor for_test(owner(), ST(token_pos)); 2927 TestGraphVisitor for_test(owner(), ST(token_pos));
3082 check_is_null->Visit(&for_test); 2928 check_is_null->Visit(&for_test);
3083 2929
3084 EffectGraphVisitor for_true(owner()); 2930 EffectGraphVisitor for_true(owner());
3085 EffectGraphVisitor for_false(owner()); 2931 EffectGraphVisitor for_false(owner());
3086 2932
3087 InstanceSetterNode* setter = 2933 InstanceSetterNode* setter = new (Z) InstanceSetterNode(
3088 new(Z) InstanceSetterNode(token_pos, 2934 token_pos, load_temp, node->field_name(), node->value());
3089 load_temp,
3090 node->field_name(),
3091 node->value());
3092 setter->Visit(&for_false); 2935 setter->Visit(&for_false);
3093 Join(for_test, for_true, for_false); 2936 Join(for_test, for_true, for_false);
3094 return; 2937 return;
3095 } 2938 }
3096 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2939 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3097 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); 2940 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
3098 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded); 2941 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded);
3099 const String& name = 2942 const String& name =
3100 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); 2943 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
3101 const intptr_t kNumArgsChecked = 1; // Do not check value type. 2944 const intptr_t kNumArgsChecked = 1; // Do not check value type.
3102 InstanceCallInstr* call = new(Z) InstanceCallInstr(token_pos, 2945 InstanceCallInstr* call = new (Z) InstanceCallInstr(
3103 name, 2946 token_pos, name, Token::kSET, arguments, Object::null_array(),
3104 Token::kSET, 2947 kNumArgsChecked, owner()->ic_data_array());
3105 arguments,
3106 Object::null_array(),
3107 kNumArgsChecked,
3108 owner()->ic_data_array());
3109 ReturnDefinition(call); 2948 ReturnDefinition(call);
3110 } 2949 }
3111 2950
3112 2951
3113 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 2952 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
3114 const TokenPosition token_pos = node->token_pos(); 2953 const TokenPosition token_pos = node->token_pos();
3115 if (node->is_conditional()) { 2954 if (node->is_conditional()) {
3116 ValueGraphVisitor for_receiver(owner()); 2955 ValueGraphVisitor for_receiver(owner());
3117 node->receiver()->Visit(&for_receiver); 2956 node->receiver()->Visit(&for_receiver);
3118 Append(for_receiver); 2957 Append(for_receiver);
3119 Do(BuildStoreExprTemp(for_receiver.value(), token_pos)); 2958 Do(BuildStoreExprTemp(for_receiver.value(), token_pos));
3120 2959
3121 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); 2960 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
3122 LoadLocalNode* load_temp = 2961 LoadLocalNode* load_temp = new (Z) LoadLocalNode(ST(token_pos), temp_var);
3123 new(Z) LoadLocalNode(ST(token_pos), temp_var);
3124 LiteralNode* null_constant = 2962 LiteralNode* null_constant =
3125 new(Z) LiteralNode(ST(token_pos), Object::null_instance()); 2963 new (Z) LiteralNode(ST(token_pos), Object::null_instance());
3126 ComparisonNode* check_is_null = 2964 ComparisonNode* check_is_null = new (Z)
3127 new(Z) ComparisonNode(ST(token_pos), 2965 ComparisonNode(ST(token_pos), Token::kEQ, load_temp, null_constant);
3128 Token::kEQ,
3129 load_temp,
3130 null_constant);
3131 TestGraphVisitor for_test(owner(), ST(token_pos)); 2966 TestGraphVisitor for_test(owner(), ST(token_pos));
3132 check_is_null->Visit(&for_test); 2967 check_is_null->Visit(&for_test);
3133 2968
3134 ValueGraphVisitor for_true(owner()); 2969 ValueGraphVisitor for_true(owner());
3135 null_constant->Visit(&for_true); 2970 null_constant->Visit(&for_true);
3136 for_true.Do(BuildStoreExprTemp(for_true.value(), token_pos)); 2971 for_true.Do(BuildStoreExprTemp(for_true.value(), token_pos));
3137 2972
3138 ValueGraphVisitor for_false(owner()); 2973 ValueGraphVisitor for_false(owner());
3139 InstanceSetterNode* setter = 2974 InstanceSetterNode* setter = new (Z) InstanceSetterNode(
3140 new(Z) InstanceSetterNode(token_pos, 2975 token_pos, load_temp, node->field_name(), node->value());
3141 load_temp,
3142 node->field_name(),
3143 node->value());
3144 setter->Visit(&for_false); 2976 setter->Visit(&for_false);
3145 for_false.Do(BuildStoreExprTemp(for_false.value(), token_pos)); 2977 for_false.Do(BuildStoreExprTemp(for_false.value(), token_pos));
3146 2978
3147 Join(for_test, for_true, for_false); 2979 Join(for_test, for_true, for_false);
3148 ReturnDefinition(BuildLoadExprTemp(token_pos)); 2980 ReturnDefinition(BuildLoadExprTemp(token_pos));
3149 return; 2981 return;
3150 } 2982 }
3151 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2983 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3152 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); 2984 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
3153 BuildInstanceSetterArguments(node, arguments, kResultNeeded); 2985 BuildInstanceSetterArguments(node, arguments, kResultNeeded);
3154 const String& name = 2986 const String& name =
3155 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); 2987 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
3156 const intptr_t kNumArgsChecked = 1; // Do not check value type. 2988 const intptr_t kNumArgsChecked = 1; // Do not check value type.
3157 Do(new(Z) InstanceCallInstr(token_pos, 2989 Do(new (Z) InstanceCallInstr(token_pos, name, Token::kSET, arguments,
3158 name, 2990 Object::null_array(), kNumArgsChecked,
3159 Token::kSET, 2991 owner()->ic_data_array()));
3160 arguments,
3161 Object::null_array(),
3162 kNumArgsChecked,
3163 owner()->ic_data_array()));
3164 ReturnDefinition(BuildLoadExprTemp(token_pos)); 2992 ReturnDefinition(BuildLoadExprTemp(token_pos));
3165 } 2993 }
3166 2994
3167 2995
3168 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { 2996 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
3169 const String& getter_name = 2997 const String& getter_name =
3170 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name())); 2998 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name()));
3171 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2999 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3172 new(Z) ZoneGrowableArray<PushArgumentInstr*>(); 3000 new (Z) ZoneGrowableArray<PushArgumentInstr*>();
3173 Function& getter_function = Function::ZoneHandle(Z, Function::null()); 3001 Function& getter_function = Function::ZoneHandle(Z, Function::null());
3174 if (node->is_super_getter()) { 3002 if (node->is_super_getter()) {
3175 // Statically resolved instance getter, i.e. "super getter". 3003 // Statically resolved instance getter, i.e. "super getter".
3176 ASSERT(node->receiver() != NULL); 3004 ASSERT(node->receiver() != NULL);
3177 getter_function = Resolver::ResolveDynamicAnyArgs(Z, 3005 getter_function =
3178 node->cls(), getter_name); 3006 Resolver::ResolveDynamicAnyArgs(Z, node->cls(), getter_name);
3179 if (getter_function.IsNull()) { 3007 if (getter_function.IsNull()) {
3180 // Resolve and call noSuchMethod. 3008 // Resolve and call noSuchMethod.
3181 ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos()); 3009 ArgumentListNode* arguments = new (Z) ArgumentListNode(node->token_pos());
3182 arguments->Add(node->receiver()); 3010 arguments->Add(node->receiver());
3183 StaticCallInstr* call = 3011 StaticCallInstr* call = BuildStaticNoSuchMethodCall(
3184 BuildStaticNoSuchMethodCall(node->cls(), 3012 node->cls(), node->receiver(), getter_name, arguments,
3185 node->receiver(), 3013 false, // Don't save last argument.
3186 getter_name, 3014 true); // Super invocation.
3187 arguments,
3188 false, // Don't save last argument.
3189 true); // Super invocation.
3190 ReturnDefinition(call); 3015 ReturnDefinition(call);
3191 return; 3016 return;
3192 } else { 3017 } else {
3193 ValueGraphVisitor receiver_value(owner()); 3018 ValueGraphVisitor receiver_value(owner());
3194 node->receiver()->Visit(&receiver_value); 3019 node->receiver()->Visit(&receiver_value);
3195 Append(receiver_value); 3020 Append(receiver_value);
3196 arguments->Add(PushArgument(receiver_value.value())); 3021 arguments->Add(PushArgument(receiver_value.value()));
3197 } 3022 }
3198 } else { 3023 } else {
3199 getter_function = node->cls().LookupStaticFunction(getter_name); 3024 getter_function = node->cls().LookupStaticFunction(getter_name);
3200 if (getter_function.IsNull()) { 3025 if (getter_function.IsNull()) {
3201 // When the parser encounters a reference to a static field materialized 3026 // When the parser encounters a reference to a static field materialized
3202 // only by a static setter, but no corresponding static getter, it creates 3027 // only by a static setter, but no corresponding static getter, it creates
3203 // a StaticGetterNode ast node referring to the non-existing static getter 3028 // a StaticGetterNode ast node referring to the non-existing static getter
3204 // for the case this field reference appears in a left hand side 3029 // for the case this field reference appears in a left hand side
3205 // expression (the parser has not distinguished between left and right 3030 // expression (the parser has not distinguished between left and right
3206 // hand side yet at this stage). If the parser establishes later that the 3031 // hand side yet at this stage). If the parser establishes later that the
3207 // field access is part of a left hand side expression, the 3032 // field access is part of a left hand side expression, the
3208 // StaticGetterNode is transformed into a StaticSetterNode referring to 3033 // StaticGetterNode is transformed into a StaticSetterNode referring to
3209 // the existing static setter. 3034 // the existing static setter.
3210 // However, if the field reference appears in a right hand side 3035 // However, if the field reference appears in a right hand side
3211 // expression, no such transformation occurs and we land here with a 3036 // expression, no such transformation occurs and we land here with a
3212 // StaticGetterNode missing a getter function, so we throw a 3037 // StaticGetterNode missing a getter function, so we throw a
3213 // NoSuchMethodError. 3038 // NoSuchMethodError.
3214 3039
3215 // Throw a NoSuchMethodError. 3040 // Throw a NoSuchMethodError.
3216 StaticCallInstr* call = BuildThrowNoSuchMethodError( 3041 StaticCallInstr* call = BuildThrowNoSuchMethodError(
3217 node->token_pos(), 3042 node->token_pos(), node->cls(), getter_name,
3218 node->cls(),
3219 getter_name,
3220 NULL, // No Arguments to getter. 3043 NULL, // No Arguments to getter.
3221 InvocationMirror::EncodeType( 3044 InvocationMirror::EncodeType(node->cls().IsTopLevel()
3222 node->cls().IsTopLevel() ? 3045 ? InvocationMirror::kTopLevel
3223 InvocationMirror::kTopLevel : 3046 : InvocationMirror::kStatic,
3224 InvocationMirror::kStatic, 3047 InvocationMirror::kGetter));
3225 InvocationMirror::kGetter));
3226 ReturnDefinition(call); 3048 ReturnDefinition(call);
3227 return; 3049 return;
3228 } 3050 }
3229 } 3051 }
3230 ASSERT(!getter_function.IsNull()); 3052 ASSERT(!getter_function.IsNull());
3231 StaticCallInstr* call = new(Z) StaticCallInstr( 3053 StaticCallInstr* call =
3232 node->token_pos(), 3054 new (Z) StaticCallInstr(node->token_pos(), getter_function,
3233 getter_function, 3055 Object::null_array(), // No names
3234 Object::null_array(), // No names 3056 arguments, owner()->ic_data_array());
3235 arguments,
3236 owner()->ic_data_array());
3237 ReturnDefinition(call); 3057 ReturnDefinition(call);
3238 } 3058 }
3239 3059
3240 3060
3241 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, 3061 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node,
3242 bool result_is_needed) { 3062 bool result_is_needed) {
3243 const String& setter_name = 3063 const String& setter_name =
3244 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); 3064 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
3245 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3065 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3246 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); 3066 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1);
3247 const TokenPosition token_pos = node->token_pos(); 3067 const TokenPosition token_pos = node->token_pos();
3248 // A super setter is an instance setter whose setter function is 3068 // A super setter is an instance setter whose setter function is
3249 // resolved at compile time (in the caller instance getter's super class). 3069 // resolved at compile time (in the caller instance getter's super class).
3250 // Unlike a static getter, a super getter has a receiver parameter. 3070 // Unlike a static getter, a super getter has a receiver parameter.
3251 const bool is_super_setter = (node->receiver() != NULL); 3071 const bool is_super_setter = (node->receiver() != NULL);
3252 const Function& setter_function = node->function(); 3072 const Function& setter_function = node->function();
3253 StaticCallInstr* call; 3073 StaticCallInstr* call;
3254 if (setter_function.IsNull()) { 3074 if (setter_function.IsNull()) {
3255 if (is_super_setter) { 3075 if (is_super_setter) {
3256 ASSERT(node->receiver() != NULL); 3076 ASSERT(node->receiver() != NULL);
3257 // Resolve and call noSuchMethod. 3077 // Resolve and call noSuchMethod.
3258 ArgumentListNode* arguments = new(Z) ArgumentListNode(token_pos); 3078 ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos);
3259 arguments->Add(node->receiver()); 3079 arguments->Add(node->receiver());
3260 arguments->Add(node->value()); 3080 arguments->Add(node->value());
3261 call = BuildStaticNoSuchMethodCall( 3081 call = BuildStaticNoSuchMethodCall(
3262 node->cls(), 3082 node->cls(), node->receiver(), setter_name, arguments,
3263 node->receiver(),
3264 setter_name,
3265 arguments,
3266 result_is_needed, // Save last arg if result is needed. 3083 result_is_needed, // Save last arg if result is needed.
3267 true); // Super invocation. 3084 true); // Super invocation.
3268 } else { 3085 } else {
3269 // Throw a NoSuchMethodError. 3086 // Throw a NoSuchMethodError.
3270 ArgumentListNode* arguments = new(Z) ArgumentListNode(token_pos); 3087 ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos);
3271 arguments->Add(node->value()); 3088 arguments->Add(node->value());
3272 call = BuildThrowNoSuchMethodError( 3089 call = BuildThrowNoSuchMethodError(
3273 token_pos, 3090 token_pos, node->cls(), setter_name,
3274 node->cls(),
3275 setter_name,
3276 arguments, // Argument is the value passed to the setter. 3091 arguments, // Argument is the value passed to the setter.
3277 InvocationMirror::EncodeType( 3092 InvocationMirror::EncodeType(node->cls().IsTopLevel()
3278 node->cls().IsTopLevel() ? 3093 ? InvocationMirror::kTopLevel
3279 InvocationMirror::kTopLevel : 3094 : InvocationMirror::kStatic,
3280 InvocationMirror::kStatic, 3095 InvocationMirror::kSetter));
3281 InvocationMirror::kSetter));
3282 } 3096 }
3283 } else { 3097 } else {
3284 if (is_super_setter) { 3098 if (is_super_setter) {
3285 // Add receiver of instance getter. 3099 // Add receiver of instance getter.
3286 ValueGraphVisitor for_receiver(owner()); 3100 ValueGraphVisitor for_receiver(owner());
3287 node->receiver()->Visit(&for_receiver); 3101 node->receiver()->Visit(&for_receiver);
3288 Append(for_receiver); 3102 Append(for_receiver);
3289 arguments->Add(PushArgument(for_receiver.value())); 3103 arguments->Add(PushArgument(for_receiver.value()));
3290 } 3104 }
3291 ValueGraphVisitor for_value(owner()); 3105 ValueGraphVisitor for_value(owner());
3292 node->value()->Visit(&for_value); 3106 node->value()->Visit(&for_value);
3293 Append(for_value); 3107 Append(for_value);
3294 Value* value = NULL; 3108 Value* value = NULL;
3295 if (result_is_needed) { 3109 if (result_is_needed) {
3296 value = Bind(BuildStoreExprTemp(for_value.value(), token_pos)); 3110 value = Bind(BuildStoreExprTemp(for_value.value(), token_pos));
3297 } else { 3111 } else {
3298 value = for_value.value(); 3112 value = for_value.value();
3299 } 3113 }
3300 arguments->Add(PushArgument(value)); 3114 arguments->Add(PushArgument(value));
3301 3115
3302 call = new(Z) StaticCallInstr(token_pos, 3116 call = new (Z) StaticCallInstr(token_pos, setter_function,
3303 setter_function, 3117 Object::null_array(), // No names.
3304 Object::null_array(), // No names. 3118 arguments, owner()->ic_data_array());
3305 arguments,
3306 owner()->ic_data_array());
3307 } 3119 }
3308 if (result_is_needed) { 3120 if (result_is_needed) {
3309 Do(call); 3121 Do(call);
3310 ReturnDefinition(BuildLoadExprTemp(token_pos)); 3122 ReturnDefinition(BuildLoadExprTemp(token_pos));
3311 } else { 3123 } else {
3312 ReturnDefinition(call); 3124 ReturnDefinition(call);
3313 } 3125 }
3314 } 3126 }
3315 3127
3316 3128
(...skipping 19 matching lines...) Expand all
3336 return TypedData::length_offset(); 3148 return TypedData::length_offset();
3337 case MethodRecognizer::kGrowableArrayLength: 3149 case MethodRecognizer::kGrowableArrayLength:
3338 return GrowableObjectArray::length_offset(); 3150 return GrowableObjectArray::length_offset();
3339 default: 3151 default:
3340 UNREACHABLE(); 3152 UNREACHABLE();
3341 return 0; 3153 return 0;
3342 } 3154 }
3343 } 3155 }
3344 3156
3345 3157
3346 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar( 3158 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(LocalScope* scope,
3347 LocalScope* scope, TokenPosition token_pos) { 3159 TokenPosition token_pos) {
3348 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(), 3160 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(),
3349 true); // Test only. 3161 true); // Test only.
3350 return new(Z) LoadLocalInstr(*receiver_var, token_pos); 3162 return new (Z) LoadLocalInstr(*receiver_var, token_pos);
3351 } 3163 }
3352 3164
3353 3165
3354 LoadFieldInstr* EffectGraphVisitor::BuildNativeGetter( 3166 LoadFieldInstr* EffectGraphVisitor::BuildNativeGetter(
3355 NativeBodyNode* node, 3167 NativeBodyNode* node,
3356 MethodRecognizer::Kind kind, 3168 MethodRecognizer::Kind kind,
3357 intptr_t offset, 3169 intptr_t offset,
3358 const Type& type, 3170 const Type& type,
3359 intptr_t class_id) { 3171 intptr_t class_id) {
3360 Value* receiver = Bind(BuildLoadThisVar(node->scope(), node->token_pos())); 3172 Value* receiver = Bind(BuildLoadThisVar(node->scope(), node->token_pos()));
3361 LoadFieldInstr* load = new(Z) LoadFieldInstr(receiver, 3173 LoadFieldInstr* load =
3362 offset, 3174 new (Z) LoadFieldInstr(receiver, offset, type, node->token_pos());
3363 type,
3364 node->token_pos());
3365 load->set_result_cid(class_id); 3175 load->set_result_cid(class_id);
3366 load->set_recognized_kind(kind); 3176 load->set_recognized_kind(kind);
3367 return load; 3177 return load;
3368 } 3178 }
3369 3179
3370 3180
3371 ConstantInstr* EffectGraphVisitor::DoNativeSetterStoreValue( 3181 ConstantInstr* EffectGraphVisitor::DoNativeSetterStoreValue(
3372 NativeBodyNode* node, 3182 NativeBodyNode* node,
3373 intptr_t offset, 3183 intptr_t offset,
3374 StoreBarrierType emit_store_barrier) { 3184 StoreBarrierType emit_store_barrier) {
3375 Value* receiver = Bind(BuildLoadThisVar(node->scope(), node->token_pos())); 3185 Value* receiver = Bind(BuildLoadThisVar(node->scope(), node->token_pos()));
3376 LocalVariable* value_var = 3186 LocalVariable* value_var =
3377 node->scope()->LookupVariable(Symbols::Value(), true); 3187 node->scope()->LookupVariable(Symbols::Value(), true);
3378 Value* value = Bind(new(Z) LoadLocalInstr(*value_var, node->token_pos())); 3188 Value* value = Bind(new (Z) LoadLocalInstr(*value_var, node->token_pos()));
3379 StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr( 3189 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr(
3380 offset, 3190 offset, receiver, value, emit_store_barrier, node->token_pos());
3381 receiver,
3382 value,
3383 emit_store_barrier,
3384 node->token_pos());
3385 Do(store); 3191 Do(store);
3386 return new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null())); 3192 return new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()));
3387 } 3193 }
3388 3194
3389 3195
3390 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { 3196 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
3391 const Function& function = owner()->function(); 3197 const Function& function = owner()->function();
3392 const TokenPosition token_pos = node->token_pos(); 3198 const TokenPosition token_pos = node->token_pos();
3393 if (!function.IsClosureFunction()) { 3199 if (!function.IsClosureFunction()) {
3394 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); 3200 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
3395 switch (kind) { 3201 switch (kind) {
3396 case MethodRecognizer::kObjectEquals: { 3202 case MethodRecognizer::kObjectEquals: {
3397 Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos)); 3203 Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos));
3398 LocalVariable* other_var = 3204 LocalVariable* other_var =
3399 node->scope()->LookupVariable(Symbols::Other(), 3205 node->scope()->LookupVariable(Symbols::Other(),
3400 true); // Test only. 3206 true); // Test only.
3401 Value* other = Bind(new(Z) LoadLocalInstr(*other_var, token_pos)); 3207 Value* other = Bind(new (Z) LoadLocalInstr(*other_var, token_pos));
3402 // Receiver is not a number because numbers override equality. 3208 // Receiver is not a number because numbers override equality.
3403 const bool kNoNumberCheck = false; 3209 const bool kNoNumberCheck = false;
3404 StrictCompareInstr* compare = 3210 StrictCompareInstr* compare = new (Z) StrictCompareInstr(
3405 new(Z) StrictCompareInstr(token_pos, 3211 token_pos, Token::kEQ_STRICT, receiver, other, kNoNumberCheck);
3406 Token::kEQ_STRICT,
3407 receiver,
3408 other,
3409 kNoNumberCheck);
3410 return ReturnDefinition(compare); 3212 return ReturnDefinition(compare);
3411 } 3213 }
3412 case MethodRecognizer::kStringBaseLength: 3214 case MethodRecognizer::kStringBaseLength:
3413 case MethodRecognizer::kStringBaseIsEmpty: { 3215 case MethodRecognizer::kStringBaseIsEmpty: {
3414 // Treat length loads as mutable (i.e. affected by side effects) to 3216 // Treat length loads as mutable (i.e. affected by side effects) to
3415 // avoid hoisting them since we can't hoist the preceding class-check. 3217 // avoid hoisting them since we can't hoist the preceding class-check.
3416 // This is because of externalization of strings that affects their 3218 // This is because of externalization of strings that affects their
3417 // class-id. 3219 // class-id.
3418 LoadFieldInstr* load = BuildNativeGetter( 3220 LoadFieldInstr* load = BuildNativeGetter(
3419 node, MethodRecognizer::kStringBaseLength, String::length_offset(), 3221 node, MethodRecognizer::kStringBaseLength, String::length_offset(),
3420 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); 3222 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid);
3421 load->set_is_immutable(!FLAG_support_externalizable_strings); 3223 load->set_is_immutable(!FLAG_support_externalizable_strings);
3422 if (kind == MethodRecognizer::kStringBaseLength) { 3224 if (kind == MethodRecognizer::kStringBaseLength) {
3423 return ReturnDefinition(load); 3225 return ReturnDefinition(load);
3424 } 3226 }
3425 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty); 3227 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty);
3426 Value* zero_val = Bind(new(Z) ConstantInstr( 3228 Value* zero_val =
3427 Smi::ZoneHandle(Z, Smi::New(0)))); 3229 Bind(new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(0))));
3428 Value* load_val = Bind(load); 3230 Value* load_val = Bind(load);
3429 StrictCompareInstr* compare = 3231 StrictCompareInstr* compare = new (Z)
3430 new(Z) StrictCompareInstr(token_pos, 3232 StrictCompareInstr(token_pos, Token::kEQ_STRICT, load_val, zero_val,
3431 Token::kEQ_STRICT, 3233 false); // No number check.
3432 load_val,
3433 zero_val,
3434 false); // No number check.
3435 return ReturnDefinition(compare); 3234 return ReturnDefinition(compare);
3436 } 3235 }
3437 case MethodRecognizer::kGrowableArrayLength: 3236 case MethodRecognizer::kGrowableArrayLength:
3438 case MethodRecognizer::kObjectArrayLength: 3237 case MethodRecognizer::kObjectArrayLength:
3439 case MethodRecognizer::kImmutableArrayLength: 3238 case MethodRecognizer::kImmutableArrayLength:
3440 case MethodRecognizer::kTypedDataLength: { 3239 case MethodRecognizer::kTypedDataLength: {
3441 LoadFieldInstr* load = BuildNativeGetter( 3240 LoadFieldInstr* load =
3442 node, kind, OffsetForLengthGetter(kind), 3241 BuildNativeGetter(node, kind, OffsetForLengthGetter(kind),
3443 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); 3242 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid);
3444 load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength); 3243 load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength);
3445 return ReturnDefinition(load); 3244 return ReturnDefinition(load);
3446 } 3245 }
3447 case MethodRecognizer::kClassIDgetID: { 3246 case MethodRecognizer::kClassIDgetID: {
3448 LocalVariable* value_var = 3247 LocalVariable* value_var =
3449 node->scope()->LookupVariable(Symbols::Value(), true); 3248 node->scope()->LookupVariable(Symbols::Value(), true);
3450 Value* value = Bind(new(Z) LoadLocalInstr(*value_var, token_pos)); 3249 Value* value = Bind(new (Z) LoadLocalInstr(*value_var, token_pos));
3451 LoadClassIdInstr* load = new(Z) LoadClassIdInstr(value); 3250 LoadClassIdInstr* load = new (Z) LoadClassIdInstr(value);
3452 return ReturnDefinition(load); 3251 return ReturnDefinition(load);
3453 } 3252 }
3454 case MethodRecognizer::kGrowableArrayCapacity: { 3253 case MethodRecognizer::kGrowableArrayCapacity: {
3455 Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos)); 3254 Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos));
3456 LoadFieldInstr* data_load = new(Z) LoadFieldInstr( 3255 LoadFieldInstr* data_load =
3457 receiver, 3256 new (Z) LoadFieldInstr(receiver, Array::data_offset(),
3458 Array::data_offset(), 3257 Object::dynamic_type(), node->token_pos());
3459 Object::dynamic_type(),
3460 node->token_pos());
3461 data_load->set_result_cid(kArrayCid); 3258 data_load->set_result_cid(kArrayCid);
3462 Value* data = Bind(data_load); 3259 Value* data = Bind(data_load);
3463 LoadFieldInstr* length_load = new(Z) LoadFieldInstr( 3260 LoadFieldInstr* length_load = new (Z) LoadFieldInstr(
3464 data, 3261 data, Array::length_offset(), Type::ZoneHandle(Z, Type::SmiType()),
3465 Array::length_offset(),
3466 Type::ZoneHandle(Z, Type::SmiType()),
3467 node->token_pos()); 3262 node->token_pos());
3468 length_load->set_result_cid(kSmiCid); 3263 length_load->set_result_cid(kSmiCid);
3469 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength); 3264 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength);
3470 return ReturnDefinition(length_load); 3265 return ReturnDefinition(length_load);
3471 } 3266 }
3472 case MethodRecognizer::kObjectArrayAllocate: { 3267 case MethodRecognizer::kObjectArrayAllocate: {
3473 LocalVariable* type_args_parameter = 3268 LocalVariable* type_args_parameter = node->scope()->LookupVariable(
3474 node->scope()->LookupVariable(Symbols::TypeArgumentsParameter(), 3269 Symbols::TypeArgumentsParameter(), true);
3475 true);
3476 Value* element_type = 3270 Value* element_type =
3477 Bind(new(Z) LoadLocalInstr(*type_args_parameter, token_pos)); 3271 Bind(new (Z) LoadLocalInstr(*type_args_parameter, token_pos));
3478 LocalVariable* length_parameter = 3272 LocalVariable* length_parameter =
3479 node->scope()->LookupVariable(Symbols::Length(), true); 3273 node->scope()->LookupVariable(Symbols::Length(), true);
3480 Value* length = 3274 Value* length =
3481 Bind(new(Z) LoadLocalInstr(*length_parameter, token_pos)); 3275 Bind(new (Z) LoadLocalInstr(*length_parameter, token_pos));
3482 CreateArrayInstr* create_array = 3276 CreateArrayInstr* create_array =
3483 new CreateArrayInstr(token_pos, element_type, length); 3277 new CreateArrayInstr(token_pos, element_type, length);
3484 return ReturnDefinition(create_array); 3278 return ReturnDefinition(create_array);
3485 } 3279 }
3486 case MethodRecognizer::kBigint_getDigits: { 3280 case MethodRecognizer::kBigint_getDigits: {
3487 return ReturnDefinition(BuildNativeGetter( 3281 return ReturnDefinition(BuildNativeGetter(
3488 node, kind, Bigint::digits_offset(), 3282 node, kind, Bigint::digits_offset(), Object::dynamic_type(),
3489 Object::dynamic_type(),
3490 kTypedDataUint32ArrayCid)); 3283 kTypedDataUint32ArrayCid));
3491 } 3284 }
3492 case MethodRecognizer::kBigint_getUsed: { 3285 case MethodRecognizer::kBigint_getUsed: {
3493 return ReturnDefinition(BuildNativeGetter( 3286 return ReturnDefinition(
3494 node, kind, Bigint::used_offset(), 3287 BuildNativeGetter(node, kind, Bigint::used_offset(),
3495 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid)); 3288 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid));
3496 } 3289 }
3497 case MethodRecognizer::kLinkedHashMap_getIndex: { 3290 case MethodRecognizer::kLinkedHashMap_getIndex: {
3498 return ReturnDefinition(BuildNativeGetter( 3291 return ReturnDefinition(
3499 node, kind, LinkedHashMap::index_offset(), 3292 BuildNativeGetter(node, kind, LinkedHashMap::index_offset(),
3500 Object::dynamic_type(), 3293 Object::dynamic_type(), kDynamicCid));
3501 kDynamicCid));
3502 } 3294 }
3503 case MethodRecognizer::kLinkedHashMap_setIndex: { 3295 case MethodRecognizer::kLinkedHashMap_setIndex: {
3504 return ReturnDefinition(DoNativeSetterStoreValue( 3296 return ReturnDefinition(DoNativeSetterStoreValue(
3505 node, LinkedHashMap::index_offset(), kEmitStoreBarrier)); 3297 node, LinkedHashMap::index_offset(), kEmitStoreBarrier));
3506 } 3298 }
3507 case MethodRecognizer::kLinkedHashMap_getData: { 3299 case MethodRecognizer::kLinkedHashMap_getData: {
3508 return ReturnDefinition(BuildNativeGetter( 3300 return ReturnDefinition(
3509 node, kind, LinkedHashMap::data_offset(), 3301 BuildNativeGetter(node, kind, LinkedHashMap::data_offset(),
3510 Object::dynamic_type(), 3302 Object::dynamic_type(), kArrayCid));
3511 kArrayCid));
3512 } 3303 }
3513 case MethodRecognizer::kLinkedHashMap_setData: { 3304 case MethodRecognizer::kLinkedHashMap_setData: {
3514 return ReturnDefinition(DoNativeSetterStoreValue( 3305 return ReturnDefinition(DoNativeSetterStoreValue(
3515 node, LinkedHashMap::data_offset(), kEmitStoreBarrier)); 3306 node, LinkedHashMap::data_offset(), kEmitStoreBarrier));
3516 } 3307 }
3517 case MethodRecognizer::kLinkedHashMap_getHashMask: { 3308 case MethodRecognizer::kLinkedHashMap_getHashMask: {
3518 return ReturnDefinition(BuildNativeGetter( 3309 return ReturnDefinition(
3519 node, kind, LinkedHashMap::hash_mask_offset(), 3310 BuildNativeGetter(node, kind, LinkedHashMap::hash_mask_offset(),
3520 Type::ZoneHandle(Z, Type::SmiType()), 3311 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid));
3521 kSmiCid));
3522 } 3312 }
3523 case MethodRecognizer::kLinkedHashMap_setHashMask: { 3313 case MethodRecognizer::kLinkedHashMap_setHashMask: {
3524 // Smi field; no barrier needed. 3314 // Smi field; no barrier needed.
3525 return ReturnDefinition(DoNativeSetterStoreValue( 3315 return ReturnDefinition(DoNativeSetterStoreValue(
3526 node, LinkedHashMap::hash_mask_offset(), kNoStoreBarrier)); 3316 node, LinkedHashMap::hash_mask_offset(), kNoStoreBarrier));
3527 } 3317 }
3528 case MethodRecognizer::kLinkedHashMap_getUsedData: { 3318 case MethodRecognizer::kLinkedHashMap_getUsedData: {
3529 return ReturnDefinition(BuildNativeGetter( 3319 return ReturnDefinition(
3530 node, kind, LinkedHashMap::used_data_offset(), 3320 BuildNativeGetter(node, kind, LinkedHashMap::used_data_offset(),
3531 Type::ZoneHandle(Z, Type::SmiType()), 3321 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid));
3532 kSmiCid));
3533 } 3322 }
3534 case MethodRecognizer::kLinkedHashMap_setUsedData: { 3323 case MethodRecognizer::kLinkedHashMap_setUsedData: {
3535 // Smi field; no barrier needed. 3324 // Smi field; no barrier needed.
3536 return ReturnDefinition(DoNativeSetterStoreValue( 3325 return ReturnDefinition(DoNativeSetterStoreValue(
3537 node, LinkedHashMap::used_data_offset(), kNoStoreBarrier)); 3326 node, LinkedHashMap::used_data_offset(), kNoStoreBarrier));
3538 } 3327 }
3539 case MethodRecognizer::kLinkedHashMap_getDeletedKeys: { 3328 case MethodRecognizer::kLinkedHashMap_getDeletedKeys: {
3540 return ReturnDefinition(BuildNativeGetter( 3329 return ReturnDefinition(
3541 node, kind, LinkedHashMap::deleted_keys_offset(), 3330 BuildNativeGetter(node, kind, LinkedHashMap::deleted_keys_offset(),
3542 Type::ZoneHandle(Z, Type::SmiType()), 3331 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid));
3543 kSmiCid));
3544 } 3332 }
3545 case MethodRecognizer::kLinkedHashMap_setDeletedKeys: { 3333 case MethodRecognizer::kLinkedHashMap_setDeletedKeys: {
3546 // Smi field; no barrier needed. 3334 // Smi field; no barrier needed.
3547 return ReturnDefinition(DoNativeSetterStoreValue( 3335 return ReturnDefinition(DoNativeSetterStoreValue(
3548 node, LinkedHashMap::deleted_keys_offset(), kNoStoreBarrier)); 3336 node, LinkedHashMap::deleted_keys_offset(), kNoStoreBarrier));
3549 } 3337 }
3550 case MethodRecognizer::kBigint_getNeg: { 3338 case MethodRecognizer::kBigint_getNeg: {
3551 return ReturnDefinition(BuildNativeGetter( 3339 return ReturnDefinition(
3552 node, kind, Bigint::neg_offset(), 3340 BuildNativeGetter(node, kind, Bigint::neg_offset(),
3553 Type::ZoneHandle(Z, Type::BoolType()), kBoolCid)); 3341 Type::ZoneHandle(Z, Type::BoolType()), kBoolCid));
3554 } 3342 }
3555 default: 3343 default:
3556 break; 3344 break;
3557 } 3345 }
3558 } 3346 }
3559 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); 3347 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode");
3560 NativeCallInstr* native_call = new(Z) NativeCallInstr(node); 3348 NativeCallInstr* native_call = new (Z) NativeCallInstr(node);
3561 ReturnDefinition(native_call); 3349 ReturnDefinition(native_call);
3562 } 3350 }
3563 3351
3564 3352
3565 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { 3353 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) {
3566 // PrimaryNodes are temporary during parsing. 3354 // PrimaryNodes are temporary during parsing.
3567 UNREACHABLE(); 3355 UNREACHABLE();
3568 } 3356 }
3569 3357
3570 3358
(...skipping 18 matching lines...) Expand all
3589 // variables, or for generated code that has no source position. 3377 // variables, or for generated code that has no source position.
3590 if (FLAG_support_debugger) { 3378 if (FLAG_support_debugger) {
3591 AstNode* rhs = node->value(); 3379 AstNode* rhs = node->value();
3592 if (rhs->IsAssignableNode()) { 3380 if (rhs->IsAssignableNode()) {
3593 rhs = rhs->AsAssignableNode()->expr(); 3381 rhs = rhs->AsAssignableNode()->expr();
3594 } 3382 }
3595 if ((rhs->IsLiteralNode() || 3383 if ((rhs->IsLiteralNode() ||
3596 (rhs->IsLoadLocalNode() && 3384 (rhs->IsLoadLocalNode() &&
3597 !rhs->AsLoadLocalNode()->local().IsInternal()) || 3385 !rhs->AsLoadLocalNode()->local().IsInternal()) ||
3598 rhs->IsClosureNode()) && 3386 rhs->IsClosureNode()) &&
3599 !node->local().IsInternal() && 3387 !node->local().IsInternal() && node->token_pos().IsDebugPause()) {
3600 node->token_pos().IsDebugPause()) { 3388 AddInstruction(new (Z) DebugStepCheckInstr(
3601 AddInstruction(new(Z) DebugStepCheckInstr(
3602 node->token_pos(), RawPcDescriptors::kRuntimeCall)); 3389 node->token_pos(), RawPcDescriptors::kRuntimeCall));
3603 } 3390 }
3604 } 3391 }
3605 3392
3606 ValueGraphVisitor for_value(owner()); 3393 ValueGraphVisitor for_value(owner());
3607 node->value()->Visit(&for_value); 3394 node->value()->Visit(&for_value);
3608 Append(for_value); 3395 Append(for_value);
3609 Value* store_value = for_value.value(); 3396 Value* store_value = for_value.value();
3610 if (Isolate::Current()->type_checks()) { 3397 if (Isolate::Current()->type_checks()) {
3611 store_value = BuildAssignableValue(node->value()->token_pos(), 3398 store_value =
3612 store_value, 3399 BuildAssignableValue(node->value()->token_pos(), store_value,
3613 node->local().type(), 3400 node->local().type(), node->local().name());
3614 node->local().name());
3615 } 3401 }
3616 Definition* store = BuildStoreLocal(node->local(), 3402 Definition* store =
3617 store_value, 3403 BuildStoreLocal(node->local(), store_value, node->token_pos());
3618 node->token_pos());
3619 ReturnDefinition(store); 3404 ReturnDefinition(store);
3620 } 3405 }
3621 3406
3622 3407
3623 void EffectGraphVisitor::VisitLoadInstanceFieldNode( 3408 void EffectGraphVisitor::VisitLoadInstanceFieldNode(
3624 LoadInstanceFieldNode* node) { 3409 LoadInstanceFieldNode* node) {
3625 ValueGraphVisitor for_instance(owner()); 3410 ValueGraphVisitor for_instance(owner());
3626 node->instance()->Visit(&for_instance); 3411 node->instance()->Visit(&for_instance);
3627 Append(for_instance); 3412 Append(for_instance);
3628 LoadFieldInstr* load = new(Z) LoadFieldInstr( 3413 LoadFieldInstr* load = new (Z) LoadFieldInstr(
3629 for_instance.value(), 3414 for_instance.value(), &node->field(),
3630 &node->field(), 3415 AbstractType::ZoneHandle(Z, node->field().type()), node->token_pos());
3631 AbstractType::ZoneHandle(Z, node->field().type()),
3632 node->token_pos());
3633 if (node->field().guarded_cid() != kIllegalCid) { 3416 if (node->field().guarded_cid() != kIllegalCid) {
3634 if (!node->field().is_nullable() || 3417 if (!node->field().is_nullable() ||
3635 (node->field().guarded_cid() == kNullCid)) { 3418 (node->field().guarded_cid() == kNullCid)) {
3636 load->set_result_cid(node->field().guarded_cid()); 3419 load->set_result_cid(node->field().guarded_cid());
3637 } 3420 }
3638 owner()->parsed_function().AddToGuardedFields(&node->field()); 3421 owner()->parsed_function().AddToGuardedFields(&node->field());
3639 } 3422 }
3640 ReturnDefinition(load); 3423 ReturnDefinition(load);
3641 } 3424 }
3642 3425
3643 3426
3644 void EffectGraphVisitor::VisitStoreInstanceFieldNode( 3427 void EffectGraphVisitor::VisitStoreInstanceFieldNode(
3645 StoreInstanceFieldNode* node) { 3428 StoreInstanceFieldNode* node) {
3646 const TokenPosition token_pos = node->token_pos(); 3429 const TokenPosition token_pos = node->token_pos();
3647 ValueGraphVisitor for_instance(owner()); 3430 ValueGraphVisitor for_instance(owner());
3648 node->instance()->Visit(&for_instance); 3431 node->instance()->Visit(&for_instance);
3649 Append(for_instance); 3432 Append(for_instance);
3650 ValueGraphVisitor for_value(owner()); 3433 ValueGraphVisitor for_value(owner());
3651 node->value()->Visit(&for_value); 3434 node->value()->Visit(&for_value);
3652 Append(for_value); 3435 Append(for_value);
3653 Value* store_value = for_value.value(); 3436 Value* store_value = for_value.value();
3654 if (Isolate::Current()->type_checks()) { 3437 if (Isolate::Current()->type_checks()) {
3655 const AbstractType& type = 3438 const AbstractType& type =
3656 AbstractType::ZoneHandle(Z, node->field().type()); 3439 AbstractType::ZoneHandle(Z, node->field().type());
3657 const String& dst_name = String::ZoneHandle(Z, node->field().name()); 3440 const String& dst_name = String::ZoneHandle(Z, node->field().name());
3658 store_value = BuildAssignableValue(node->value()->token_pos(), 3441 store_value = BuildAssignableValue(node->value()->token_pos(), store_value,
3659 store_value, 3442 type, dst_name);
3660 type,
3661 dst_name);
3662 } 3443 }
3663 3444
3664 if (FLAG_use_field_guards) { 3445 if (FLAG_use_field_guards) {
3665 store_value = Bind(BuildStoreExprTemp(store_value, token_pos)); 3446 store_value = Bind(BuildStoreExprTemp(store_value, token_pos));
3666 GuardFieldClassInstr* guard_field_class = 3447 GuardFieldClassInstr* guard_field_class = new (Z) GuardFieldClassInstr(
3667 new(Z) GuardFieldClassInstr(store_value, 3448 store_value, node->field(), thread()->GetNextDeoptId());
3668 node->field(),
3669 thread()->GetNextDeoptId());
3670 AddInstruction(guard_field_class); 3449 AddInstruction(guard_field_class);
3671 store_value = Bind(BuildLoadExprTemp(token_pos)); 3450 store_value = Bind(BuildLoadExprTemp(token_pos));
3672 GuardFieldLengthInstr* guard_field_length = 3451 GuardFieldLengthInstr* guard_field_length = new (Z) GuardFieldLengthInstr(
3673 new(Z) GuardFieldLengthInstr(store_value, 3452 store_value, node->field(), thread()->GetNextDeoptId());
3674 node->field(),
3675 thread()->GetNextDeoptId());
3676 AddInstruction(guard_field_length); 3453 AddInstruction(guard_field_length);
3677 store_value = Bind(BuildLoadExprTemp(token_pos)); 3454 store_value = Bind(BuildLoadExprTemp(token_pos));
3678 } 3455 }
3679 StoreInstanceFieldInstr* store = 3456 StoreInstanceFieldInstr* store = new (Z)
3680 new(Z) StoreInstanceFieldInstr(node->field(), 3457 StoreInstanceFieldInstr(node->field(), for_instance.value(), store_value,
3681 for_instance.value(), 3458 kEmitStoreBarrier, token_pos);
3682 store_value,
3683 kEmitStoreBarrier,
3684 token_pos);
3685 // Maybe initializing unboxed store. 3459 // Maybe initializing unboxed store.
3686 store->set_is_initialization(node->is_initializer()); 3460 store->set_is_initialization(node->is_initializer());
3687 ReturnDefinition(store); 3461 ReturnDefinition(store);
3688 } 3462 }
3689 3463
3690 3464
3691 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { 3465 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
3692 const TokenPosition token_pos = node->token_pos(); 3466 const TokenPosition token_pos = node->token_pos();
3693 if (node->field().is_const()) { 3467 if (node->field().is_const()) {
3694 ASSERT(node->field().StaticValue() != Object::sentinel().raw()); 3468 ASSERT(node->field().StaticValue() != Object::sentinel().raw());
3695 ASSERT(node->field().StaticValue() != 3469 ASSERT(node->field().StaticValue() != Object::transition_sentinel().raw());
3696 Object::transition_sentinel().raw()); 3470 Definition* result = new (Z) ConstantInstr(
3697 Definition* result = new(Z) ConstantInstr(
3698 Instance::ZoneHandle(Z, node->field().StaticValue()), token_pos); 3471 Instance::ZoneHandle(Z, node->field().StaticValue()), token_pos);
3699 return ReturnDefinition(result); 3472 return ReturnDefinition(result);
3700 } 3473 }
3701 Value* field_value = Bind(new(Z) ConstantInstr( 3474 Value* field_value = Bind(new (Z) ConstantInstr(
3702 Field::ZoneHandle(Z, node->field().Original()), token_pos)); 3475 Field::ZoneHandle(Z, node->field().Original()), token_pos));
3703 LoadStaticFieldInstr* load = 3476 LoadStaticFieldInstr* load =
3704 new(Z) LoadStaticFieldInstr(field_value, token_pos); 3477 new (Z) LoadStaticFieldInstr(field_value, token_pos);
3705 ReturnDefinition(load); 3478 ReturnDefinition(load);
3706 } 3479 }
3707 3480
3708 3481
3709 Definition* EffectGraphVisitor::BuildStoreStaticField( 3482 Definition* EffectGraphVisitor::BuildStoreStaticField(
3710 StoreStaticFieldNode* node, 3483 StoreStaticFieldNode* node,
3711 bool result_is_needed, 3484 bool result_is_needed,
3712 TokenPosition token_pos) { 3485 TokenPosition token_pos) {
3713 if (FLAG_support_debugger) { 3486 if (FLAG_support_debugger) {
3714 // If the right hand side is an expression that does not contain 3487 // If the right hand side is an expression that does not contain
3715 // a safe point for the debugger to stop, add an explicit stub 3488 // a safe point for the debugger to stop, add an explicit stub
3716 // call. 3489 // call.
3717 AstNode* rhs = node->value(); 3490 AstNode* rhs = node->value();
3718 if (rhs->IsAssignableNode()) { 3491 if (rhs->IsAssignableNode()) {
3719 rhs = rhs->AsAssignableNode()->expr(); 3492 rhs = rhs->AsAssignableNode()->expr();
3720 } 3493 }
3721 if ((rhs->IsLiteralNode() || 3494 if ((rhs->IsLiteralNode() || rhs->IsLoadLocalNode() ||
3722 rhs->IsLoadLocalNode() ||
3723 rhs->IsClosureNode()) && 3495 rhs->IsClosureNode()) &&
3724 node->token_pos().IsDebugPause()) { 3496 node->token_pos().IsDebugPause()) {
3725 AddInstruction(new(Z) DebugStepCheckInstr( 3497 AddInstruction(new (Z) DebugStepCheckInstr(
3726 node->token_pos(), RawPcDescriptors::kRuntimeCall)); 3498 node->token_pos(), RawPcDescriptors::kRuntimeCall));
3727 } 3499 }
3728 } 3500 }
3729 3501
3730 ValueGraphVisitor for_value(owner()); 3502 ValueGraphVisitor for_value(owner());
3731 node->value()->Visit(&for_value); 3503 node->value()->Visit(&for_value);
3732 Append(for_value); 3504 Append(for_value);
3733 Value* store_value = NULL; 3505 Value* store_value = NULL;
3734 if (result_is_needed) { 3506 if (result_is_needed) {
3735 store_value = Bind(BuildStoreExprTemp(for_value.value(), token_pos)); 3507 store_value = Bind(BuildStoreExprTemp(for_value.value(), token_pos));
3736 } else { 3508 } else {
3737 store_value = for_value.value(); 3509 store_value = for_value.value();
3738 } 3510 }
3739 StoreStaticFieldInstr* store = 3511 StoreStaticFieldInstr* store =
3740 new(Z) StoreStaticFieldInstr(node->field(), store_value, token_pos); 3512 new (Z) StoreStaticFieldInstr(node->field(), store_value, token_pos);
3741 3513
3742 if (result_is_needed) { 3514 if (result_is_needed) {
3743 Do(store); 3515 Do(store);
3744 return BuildLoadExprTemp(token_pos); 3516 return BuildLoadExprTemp(token_pos);
3745 } else { 3517 } else {
3746 return store; 3518 return store;
3747 } 3519 }
3748 } 3520 }
3749 3521
3750 3522
3751 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { 3523 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
3752 ReturnDefinition( 3524 ReturnDefinition(
3753 BuildStoreStaticField(node, kResultNotNeeded, node->token_pos())); 3525 BuildStoreStaticField(node, kResultNotNeeded, node->token_pos()));
3754 } 3526 }
3755 3527
3756 3528
3757 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { 3529 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
3758 ReturnDefinition( 3530 ReturnDefinition(
3759 BuildStoreStaticField(node, kResultNeeded, node->token_pos())); 3531 BuildStoreStaticField(node, kResultNeeded, node->token_pos()));
3760 } 3532 }
3761 3533
3762 3534
3763 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { 3535 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
3764 Function* super_function = NULL; 3536 Function* super_function = NULL;
3765 if (node->IsSuperLoad()) { 3537 if (node->IsSuperLoad()) {
3766 // Resolve the load indexed operator in the super class. 3538 // Resolve the load indexed operator in the super class.
3767 super_function = &Function::ZoneHandle(Z, Resolver::ResolveDynamicAnyArgs(Z, 3539 super_function = &Function::ZoneHandle(
3768 node->super_class(), Symbols::IndexToken())); 3540 Z, Resolver::ResolveDynamicAnyArgs(Z, node->super_class(),
3541 Symbols::IndexToken()));
3769 if (super_function->IsNull()) { 3542 if (super_function->IsNull()) {
3770 // Could not resolve super operator. Generate call noSuchMethod() of the 3543 // Could not resolve super operator. Generate call noSuchMethod() of the
3771 // super class instead. 3544 // super class instead.
3772 ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos()); 3545 ArgumentListNode* arguments = new (Z) ArgumentListNode(node->token_pos());
3773 arguments->Add(node->array()); 3546 arguments->Add(node->array());
3774 arguments->Add(node->index_expr()); 3547 arguments->Add(node->index_expr());
3775 StaticCallInstr* call = 3548 StaticCallInstr* call = BuildStaticNoSuchMethodCall(
3776 BuildStaticNoSuchMethodCall(node->super_class(), 3549 node->super_class(), node->array(), Symbols::IndexToken(), arguments,
3777 node->array(), 3550 false, // Don't save last arg.
3778 Symbols::IndexToken(), 3551 true); // Super invocation.
3779 arguments,
3780 false, // Don't save last arg.
3781 true); // Super invocation.
3782 ReturnDefinition(call); 3552 ReturnDefinition(call);
3783 return; 3553 return;
3784 } 3554 }
3785 } 3555 }
3786 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3556 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3787 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); 3557 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
3788 ValueGraphVisitor for_array(owner()); 3558 ValueGraphVisitor for_array(owner());
3789 node->array()->Visit(&for_array); 3559 node->array()->Visit(&for_array);
3790 Append(for_array); 3560 Append(for_array);
3791 arguments->Add(PushArgument(for_array.value())); 3561 arguments->Add(PushArgument(for_array.value()));
3792 3562
3793 ValueGraphVisitor for_index(owner()); 3563 ValueGraphVisitor for_index(owner());
3794 node->index_expr()->Visit(&for_index); 3564 node->index_expr()->Visit(&for_index);
3795 Append(for_index); 3565 Append(for_index);
3796 arguments->Add(PushArgument(for_index.value())); 3566 arguments->Add(PushArgument(for_index.value()));
3797 3567
3798 if (super_function != NULL) { 3568 if (super_function != NULL) {
3799 // Generate static call to super operator. 3569 // Generate static call to super operator.
3800 StaticCallInstr* load = new(Z) StaticCallInstr(node->token_pos(), 3570 StaticCallInstr* load = new (Z) StaticCallInstr(
3801 *super_function, 3571 node->token_pos(), *super_function, Object::null_array(), arguments,
3802 Object::null_array(), 3572 owner()->ic_data_array());
3803 arguments,
3804 owner()->ic_data_array());
3805 ReturnDefinition(load); 3573 ReturnDefinition(load);
3806 } else { 3574 } else {
3807 // Generate dynamic call to index operator. 3575 // Generate dynamic call to index operator.
3808 const intptr_t checked_argument_count = 1; 3576 const intptr_t checked_argument_count = 1;
3809 InstanceCallInstr* load = new(Z) InstanceCallInstr( 3577 InstanceCallInstr* load = new (Z) InstanceCallInstr(
3810 node->token_pos(), 3578 node->token_pos(), Symbols::IndexToken(), Token::kINDEX, arguments,
3811 Symbols::IndexToken(), 3579 Object::null_array(), checked_argument_count, owner()->ic_data_array());
3812 Token::kINDEX,
3813 arguments,
3814 Object::null_array(),
3815 checked_argument_count,
3816 owner()->ic_data_array());
3817 ReturnDefinition(load); 3580 ReturnDefinition(load);
3818 } 3581 }
3819 } 3582 }
3820 3583
3821 3584
3822 Definition* EffectGraphVisitor::BuildStoreIndexedValues( 3585 Definition* EffectGraphVisitor::BuildStoreIndexedValues(StoreIndexedNode* node,
3823 StoreIndexedNode* node, 3586 bool result_is_needed) {
3824 bool result_is_needed) {
3825 Function* super_function = NULL; 3587 Function* super_function = NULL;
3826 const TokenPosition token_pos = node->token_pos(); 3588 const TokenPosition token_pos = node->token_pos();
3827 if (node->IsSuperStore()) { 3589 if (node->IsSuperStore()) {
3828 // Resolve the store indexed operator in the super class. 3590 // Resolve the store indexed operator in the super class.
3829 super_function = &Function::ZoneHandle(Z, Resolver::ResolveDynamicAnyArgs(Z, 3591 super_function = &Function::ZoneHandle(
3830 node->super_class(), Symbols::AssignIndexToken())); 3592 Z, Resolver::ResolveDynamicAnyArgs(Z, node->super_class(),
3593 Symbols::AssignIndexToken()));
3831 if (super_function->IsNull()) { 3594 if (super_function->IsNull()) {
3832 // Could not resolve super operator. Generate call noSuchMethod() of the 3595 // Could not resolve super operator. Generate call noSuchMethod() of the
3833 // super class instead. 3596 // super class instead.
3834 ArgumentListNode* arguments = new(Z) ArgumentListNode(token_pos); 3597 ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos);
3835 arguments->Add(node->array()); 3598 arguments->Add(node->array());
3836 arguments->Add(node->index_expr()); 3599 arguments->Add(node->index_expr());
3837 arguments->Add(node->value()); 3600 arguments->Add(node->value());
3838 StaticCallInstr* call = BuildStaticNoSuchMethodCall( 3601 StaticCallInstr* call = BuildStaticNoSuchMethodCall(
3839 node->super_class(), 3602 node->super_class(), node->array(), Symbols::AssignIndexToken(),
3840 node->array(),
3841 Symbols::AssignIndexToken(),
3842 arguments, 3603 arguments,
3843 result_is_needed, // Save last arg if result is needed. 3604 result_is_needed, // Save last arg if result is needed.
3844 true); // Super invocation. 3605 true); // Super invocation.
3845 if (result_is_needed) { 3606 if (result_is_needed) {
3846 Do(call); 3607 Do(call);
3847 // BuildStaticNoSuchMethodCall stores the value in expression_temp. 3608 // BuildStaticNoSuchMethodCall stores the value in expression_temp.
3848 return BuildLoadExprTemp(token_pos); 3609 return BuildLoadExprTemp(token_pos);
3849 } else { 3610 } else {
3850 return call; 3611 return call;
3851 } 3612 }
3852 } 3613 }
3853 } 3614 }
3854 3615
3855 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3616 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3856 new(Z) ZoneGrowableArray<PushArgumentInstr*>(3); 3617 new (Z) ZoneGrowableArray<PushArgumentInstr*>(3);
3857 ValueGraphVisitor for_array(owner()); 3618 ValueGraphVisitor for_array(owner());
3858 node->array()->Visit(&for_array); 3619 node->array()->Visit(&for_array);
3859 Append(for_array); 3620 Append(for_array);
3860 arguments->Add(PushArgument(for_array.value())); 3621 arguments->Add(PushArgument(for_array.value()));
3861 3622
3862 ValueGraphVisitor for_index(owner()); 3623 ValueGraphVisitor for_index(owner());
3863 node->index_expr()->Visit(&for_index); 3624 node->index_expr()->Visit(&for_index);
3864 Append(for_index); 3625 Append(for_index);
3865 arguments->Add(PushArgument(for_index.value())); 3626 arguments->Add(PushArgument(for_index.value()));
3866 3627
3867 ValueGraphVisitor for_value(owner()); 3628 ValueGraphVisitor for_value(owner());
3868 node->value()->Visit(&for_value); 3629 node->value()->Visit(&for_value);
3869 Append(for_value); 3630 Append(for_value);
3870 Value* value = NULL; 3631 Value* value = NULL;
3871 if (result_is_needed) { 3632 if (result_is_needed) {
3872 value = Bind(BuildStoreExprTemp(for_value.value(), token_pos)); 3633 value = Bind(BuildStoreExprTemp(for_value.value(), token_pos));
3873 } else { 3634 } else {
3874 value = for_value.value(); 3635 value = for_value.value();
3875 } 3636 }
3876 arguments->Add(PushArgument(value)); 3637 arguments->Add(PushArgument(value));
3877 3638
3878 if (super_function != NULL) { 3639 if (super_function != NULL) {
3879 // Generate static call to super operator []=. 3640 // Generate static call to super operator []=.
3880 3641
3881 StaticCallInstr* store = 3642 StaticCallInstr* store = new (Z)
3882 new(Z) StaticCallInstr(token_pos, 3643 StaticCallInstr(token_pos, *super_function, Object::null_array(),
3883 *super_function, 3644 arguments, owner()->ic_data_array());
3884 Object::null_array(),
3885 arguments,
3886 owner()->ic_data_array());
3887 if (result_is_needed) { 3645 if (result_is_needed) {
3888 Do(store); 3646 Do(store);
3889 return BuildLoadExprTemp(token_pos); 3647 return BuildLoadExprTemp(token_pos);
3890 } else { 3648 } else {
3891 return store; 3649 return store;
3892 } 3650 }
3893 } else { 3651 } else {
3894 // Generate dynamic call to operator []=. 3652 // Generate dynamic call to operator []=.
3895 const intptr_t checked_argument_count = 2; // Do not check for value type. 3653 const intptr_t checked_argument_count = 2; // Do not check for value type.
3896 InstanceCallInstr* store = 3654 InstanceCallInstr* store = new (Z) InstanceCallInstr(
3897 new(Z) InstanceCallInstr(token_pos, 3655 token_pos, Symbols::AssignIndexToken(), Token::kASSIGN_INDEX, arguments,
3898 Symbols::AssignIndexToken(), 3656 Object::null_array(), checked_argument_count, owner()->ic_data_array());
3899 Token::kASSIGN_INDEX,
3900 arguments,
3901 Object::null_array(),
3902 checked_argument_count,
3903 owner()->ic_data_array());
3904 if (result_is_needed) { 3657 if (result_is_needed) {
3905 Do(store); 3658 Do(store);
3906 return BuildLoadExprTemp(token_pos); 3659 return BuildLoadExprTemp(token_pos);
3907 } else { 3660 } else {
3908 return store; 3661 return store;
3909 } 3662 }
3910 } 3663 }
3911 } 3664 }
3912 3665
3913 3666
3914 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { 3667 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
3915 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded)); 3668 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded));
3916 } 3669 }
3917 3670
3918 3671
3919 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { 3672 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
3920 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded)); 3673 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded));
3921 } 3674 }
3922 3675
3923 3676
3924 bool EffectGraphVisitor::HasContextScope() const { 3677 bool EffectGraphVisitor::HasContextScope() const {
3925 const ContextScope& context_scope = ContextScope::Handle( 3678 const ContextScope& context_scope =
3926 owner()->function().context_scope()); 3679 ContextScope::Handle(owner()->function().context_scope());
3927 return !context_scope.IsNull() && (context_scope.num_variables() > 0); 3680 return !context_scope.IsNull() && (context_scope.num_variables() > 0);
3928 } 3681 }
3929 3682
3930 3683
3931 void EffectGraphVisitor::UnchainContexts(intptr_t n) { 3684 void EffectGraphVisitor::UnchainContexts(intptr_t n) {
3932 // TODO(johnmccutchan): Pass this in. 3685 // TODO(johnmccutchan): Pass this in.
3933 const TokenPosition token_pos = TokenPosition::kContext; 3686 const TokenPosition token_pos = TokenPosition::kContext;
3934 if (n > 0) { 3687 if (n > 0) {
3935 Value* context = Bind(BuildCurrentContext(token_pos)); 3688 Value* context = Bind(BuildCurrentContext(token_pos));
3936 while (n-- > 0) { 3689 while (n-- > 0) {
3937 context = Bind( 3690 context = Bind(new (Z) LoadFieldInstr(context, Context::parent_offset(),
3938 new(Z) LoadFieldInstr(context, 3691 // Not an instance, no type.
3939 Context::parent_offset(), 3692 Type::ZoneHandle(Z, Type::null()),
3940 // Not an instance, no type. 3693 token_pos));
3941 Type::ZoneHandle(Z, Type::null()),
3942 token_pos));
3943 } 3694 }
3944 Do(BuildStoreContext(context, token_pos)); 3695 Do(BuildStoreContext(context, token_pos));
3945 } 3696 }
3946 } 3697 }
3947 3698
3948 3699
3949 void EffectGraphVisitor::AdjustContextLevel(LocalScope* target_scope) { 3700 void EffectGraphVisitor::AdjustContextLevel(LocalScope* target_scope) {
3950 ASSERT(target_scope != NULL); 3701 ASSERT(target_scope != NULL);
3951 intptr_t target_context_level = 0; 3702 intptr_t target_context_level = 0;
3952 if (target_scope->num_context_variables() > 0) { 3703 if (target_scope->num_context_variables() > 0) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3984 const bool is_top_level_sequence = 3735 const bool is_top_level_sequence =
3985 node == owner()->parsed_function().node_sequence(); 3736 node == owner()->parsed_function().node_sequence();
3986 // The outermost function sequence cannot contain a label. 3737 // The outermost function sequence cannot contain a label.
3987 ASSERT((node->label() == NULL) || !is_top_level_sequence); 3738 ASSERT((node->label() == NULL) || !is_top_level_sequence);
3988 NestedBlock nested_block(owner(), node); 3739 NestedBlock nested_block(owner(), node);
3989 3740
3990 if (num_context_variables > 0) { 3741 if (num_context_variables > 0) {
3991 // The local scope declares variables that are captured. 3742 // The local scope declares variables that are captured.
3992 // Allocate and chain a new context (Except don't chain when at the function 3743 // Allocate and chain a new context (Except don't chain when at the function
3993 // entry if the function does not capture any variables from outer scopes). 3744 // entry if the function does not capture any variables from outer scopes).
3994 Value* allocated_context = 3745 Value* allocated_context = Bind(
3995 Bind(new(Z) AllocateContextInstr(node->token_pos(), 3746 new (Z) AllocateContextInstr(node->token_pos(), num_context_variables));
3996 num_context_variables)); 3747 {
3997 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); 3748 LocalVariable* tmp_var = EnterTempLocalScope(allocated_context);
3998 if (!is_top_level_sequence || HasContextScope()) { 3749 if (!is_top_level_sequence || HasContextScope()) {
3999 ASSERT(is_top_level_sequence || 3750 ASSERT(is_top_level_sequence ||
4000 (nested_block.ContextLevel() == 3751 (nested_block.ContextLevel() ==
4001 nested_block.outer()->ContextLevel() + 1)); 3752 nested_block.outer()->ContextLevel() + 1));
4002 Value* tmp_val = Bind( 3753 Value* tmp_val =
4003 new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); 3754 Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos()));
4004 Value* parent_context = Bind(BuildCurrentContext(node->token_pos())); 3755 Value* parent_context = Bind(BuildCurrentContext(node->token_pos()));
4005 Do(new(Z) StoreInstanceFieldInstr(Context::parent_offset(), 3756 Do(new (Z) StoreInstanceFieldInstr(Context::parent_offset(), tmp_val,
4006 tmp_val, 3757 parent_context, kEmitStoreBarrier,
4007 parent_context, 3758 node->token_pos()));
4008 kEmitStoreBarrier,
4009 node->token_pos()));
4010 } 3759 }
4011 Do(BuildStoreContext( 3760 Do(BuildStoreContext(Bind(ExitTempLocalScope(allocated_context)),
4012 Bind(ExitTempLocalScope(allocated_context)), 3761 node->token_pos()));
4013 node->token_pos()));
4014 } 3762 }
4015 3763
4016 // If this node_sequence is the body of the function being compiled, copy 3764 // If this node_sequence is the body of the function being compiled, copy
4017 // the captured parameters from the frame into the context. 3765 // the captured parameters from the frame into the context.
4018 if (is_top_level_sequence) { 3766 if (is_top_level_sequence) {
4019 ASSERT(scope->context_level() == 1); 3767 ASSERT(scope->context_level() == 1);
4020 const int num_params = function.NumParameters(); 3768 const int num_params = function.NumParameters();
4021 int param_frame_index = (num_params == function.num_fixed_parameters()) ? 3769 int param_frame_index = (num_params == function.num_fixed_parameters())
4022 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; 3770 ? (kParamEndSlotFromFp + num_params)
3771 : kFirstLocalSlotFromFp;
4023 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { 3772 for (int pos = 0; pos < num_params; param_frame_index--, pos++) {
4024 const LocalVariable& parameter = *scope->VariableAt(pos); 3773 const LocalVariable& parameter = *scope->VariableAt(pos);
4025 ASSERT(parameter.owner() == scope); 3774 ASSERT(parameter.owner() == scope);
4026 if (parameter.is_captured()) { 3775 if (parameter.is_captured()) {
4027 // Create a temporary local describing the original position. 3776 // Create a temporary local describing the original position.
4028 const String& temp_name = Symbols::TempParam(); 3777 const String& temp_name = Symbols::TempParam();
4029 LocalVariable* temp_local = new(Z) LocalVariable( 3778 LocalVariable* temp_local =
4030 TokenPosition::kNoSource, // Token index. 3779 new (Z) LocalVariable(TokenPosition::kNoSource, // Token index.
4031 TokenPosition::kNoSource, // Token index. 3780 TokenPosition::kNoSource, // Token index.
4032 temp_name, 3781 temp_name,
4033 Object::dynamic_type()); // Type. 3782 Object::dynamic_type()); // Type.
4034 temp_local->set_index(param_frame_index); 3783 temp_local->set_index(param_frame_index);
4035 3784
4036 // Mark this local as captured parameter so that the optimizer 3785 // Mark this local as captured parameter so that the optimizer
4037 // correctly handles these when compiling try-catch: Captured 3786 // correctly handles these when compiling try-catch: Captured
4038 // parameters are not in the stack environment, therefore they 3787 // parameters are not in the stack environment, therefore they
4039 // must be skipped when emitting sync-code in try-blocks. 3788 // must be skipped when emitting sync-code in try-blocks.
4040 temp_local->set_is_captured_parameter(true); 3789 temp_local->set_is_captured_parameter(true);
4041 3790
4042 // Copy parameter from local frame to current context. 3791 // Copy parameter from local frame to current context.
4043 Value* load = Bind(BuildLoadLocal(*temp_local, node->token_pos())); 3792 Value* load = Bind(BuildLoadLocal(*temp_local, node->token_pos()));
4044 Do(BuildStoreLocal(parameter, load, ST(node->token_pos()))); 3793 Do(BuildStoreLocal(parameter, load, ST(node->token_pos())));
4045 // Write NULL to the source location to detect buggy accesses and 3794 // Write NULL to the source location to detect buggy accesses and
4046 // allow GC of passed value if it gets overwritten by a new value in 3795 // allow GC of passed value if it gets overwritten by a new value in
4047 // the function. 3796 // the function.
4048 Value* null_constant = Bind(new(Z) ConstantInstr( 3797 Value* null_constant = Bind(
4049 Object::ZoneHandle(Z, Object::null()))); 3798 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null())));
4050 Do(BuildStoreLocal(*temp_local, 3799 Do(BuildStoreLocal(*temp_local, null_constant,
4051 null_constant,
4052 ST(node->token_pos()))); 3800 ST(node->token_pos())));
4053 } 3801 }
4054 } 3802 }
4055 } 3803 }
4056 } 3804 }
4057 3805
4058 if (FLAG_support_debugger && 3806 if (FLAG_support_debugger && is_top_level_sequence &&
4059 is_top_level_sequence &&
4060 function.is_debuggable()) { 3807 function.is_debuggable()) {
4061 // Place a debug check at method entry to ensure breaking on a method always 3808 // Place a debug check at method entry to ensure breaking on a method always
4062 // happens, even if there are no assignments/calls/runtimecalls in the first 3809 // happens, even if there are no assignments/calls/runtimecalls in the first
4063 // basic block. Place this check at the last parameter to ensure parameters 3810 // basic block. Place this check at the last parameter to ensure parameters
4064 // are in scope in the debugger at method entry. 3811 // are in scope in the debugger at method entry.
4065 const int num_params = function.NumParameters(); 3812 const int num_params = function.NumParameters();
4066 TokenPosition check_pos = TokenPosition::kNoSource; 3813 TokenPosition check_pos = TokenPosition::kNoSource;
4067 if (num_params > 0) { 3814 if (num_params > 0) {
4068 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); 3815 const LocalVariable& parameter = *scope->VariableAt(num_params - 1);
4069 check_pos = parameter.token_pos(); 3816 check_pos = parameter.token_pos();
4070 } 3817 }
4071 3818
4072 if (!check_pos.IsDebugPause()) { 3819 if (!check_pos.IsDebugPause()) {
4073 // No parameters or synthetic parameters. 3820 // No parameters or synthetic parameters.
4074 check_pos = node->token_pos(); 3821 check_pos = node->token_pos();
4075 ASSERT(check_pos.IsDebugPause()); 3822 ASSERT(check_pos.IsDebugPause());
4076 } 3823 }
4077 AddInstruction(new(Z) DebugStepCheckInstr(check_pos, 3824 AddInstruction(
4078 RawPcDescriptors::kRuntimeCall)); 3825 new (Z) DebugStepCheckInstr(check_pos, RawPcDescriptors::kRuntimeCall));
4079 } 3826 }
4080 3827
4081 // This check may be deleted if the generated code is leaf. 3828 // This check may be deleted if the generated code is leaf.
4082 // Native functions don't need a stack check at entry. 3829 // Native functions don't need a stack check at entry.
4083 if (is_top_level_sequence && !function.is_native()) { 3830 if (is_top_level_sequence && !function.is_native()) {
4084 // Always allocate CheckOverflowInstr so that deopt-ids match regardless 3831 // Always allocate CheckOverflowInstr so that deopt-ids match regardless
4085 // if we inline or not. 3832 // if we inline or not.
4086 if (!function.IsImplicitGetterFunction() && 3833 if (!function.IsImplicitGetterFunction() &&
4087 !function.IsImplicitSetterFunction()) { 3834 !function.IsImplicitSetterFunction()) {
4088 CheckStackOverflowInstr* check = 3835 CheckStackOverflowInstr* check =
4089 new(Z) CheckStackOverflowInstr(node->token_pos(), 0); 3836 new (Z) CheckStackOverflowInstr(node->token_pos(), 0);
4090 // If we are inlining don't actually attach the stack check. We must still 3837 // If we are inlining don't actually attach the stack check. We must still
4091 // create the stack check in order to allocate a deopt id. 3838 // create the stack check in order to allocate a deopt id.
4092 if (!owner()->IsInlining()) { 3839 if (!owner()->IsInlining()) {
4093 AddInstruction(check); 3840 AddInstruction(check);
4094 } 3841 }
4095 } 3842 }
4096 } 3843 }
4097 3844
4098 if (Isolate::Current()->type_checks() && is_top_level_sequence) { 3845 if (Isolate::Current()->type_checks() && is_top_level_sequence) {
4099 const int num_params = function.NumParameters(); 3846 const int num_params = function.NumParameters();
4100 int pos = 0; 3847 int pos = 0;
4101 if (function.IsFactory() || 3848 if (function.IsFactory() || function.IsDynamicFunction() ||
4102 function.IsDynamicFunction() ||
4103 function.IsGenerativeConstructor()) { 3849 function.IsGenerativeConstructor()) {
4104 // Skip type checking of type arguments for factory functions. 3850 // Skip type checking of type arguments for factory functions.
4105 // Skip type checking of receiver for instance functions and constructors. 3851 // Skip type checking of receiver for instance functions and constructors.
4106 pos = 1; 3852 pos = 1;
4107 } 3853 }
4108 while (pos < num_params) { 3854 while (pos < num_params) {
4109 const LocalVariable& parameter = *scope->VariableAt(pos); 3855 const LocalVariable& parameter = *scope->VariableAt(pos);
4110 ASSERT(parameter.owner() == scope); 3856 ASSERT(parameter.owner() == scope);
4111 if (!CanSkipTypeCheck(parameter.token_pos(), 3857 if (!CanSkipTypeCheck(parameter.token_pos(), NULL, parameter.type(),
4112 NULL,
4113 parameter.type(),
4114 parameter.name())) { 3858 parameter.name())) {
4115 Value* parameter_value = 3859 Value* parameter_value =
4116 Bind(BuildLoadLocal(parameter, parameter.token_pos())); 3860 Bind(BuildLoadLocal(parameter, parameter.token_pos()));
4117 Do(BuildAssertAssignable(parameter.token_pos(), 3861 Do(BuildAssertAssignable(parameter.token_pos(), parameter_value,
4118 parameter_value, 3862 parameter.type(), parameter.name()));
4119 parameter.type(),
4120 parameter.name()));
4121 } 3863 }
4122 pos++; 3864 pos++;
4123 } 3865 }
4124 } 3866 }
4125 3867
4126 // Continuation part: 3868 // Continuation part:
4127 // If this node sequence is the body of a function with continuations, 3869 // If this node sequence is the body of a function with continuations,
4128 // leave room for a preamble. 3870 // leave room for a preamble.
4129 // The preamble is generated after visiting the body. 3871 // The preamble is generated after visiting the body.
4130 GotoInstr* preamble_start = NULL; 3872 GotoInstr* preamble_start = NULL;
4131 if (is_top_level_sequence && 3873 if (is_top_level_sequence &&
4132 (function.IsAsyncClosure() || 3874 (function.IsAsyncClosure() || function.IsSyncGenClosure() ||
4133 function.IsSyncGenClosure() || 3875 function.IsAsyncGenClosure())) {
4134 function.IsAsyncGenClosure())) { 3876 JoinEntryInstr* preamble_end = new (Z)
4135 JoinEntryInstr* preamble_end = new(Z) JoinEntryInstr( 3877 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
4136 owner()->AllocateBlockId(), owner()->try_index());
4137 ASSERT(exit() != NULL); 3878 ASSERT(exit() != NULL);
4138 exit()->Goto(preamble_end); 3879 exit()->Goto(preamble_end);
4139 ASSERT(exit()->next()->IsGoto()); 3880 ASSERT(exit()->next()->IsGoto());
4140 preamble_start = exit()->next()->AsGoto(); 3881 preamble_start = exit()->next()->AsGoto();
4141 ASSERT(preamble_start->IsGoto()); 3882 ASSERT(preamble_start->IsGoto());
4142 exit_ = preamble_end; 3883 exit_ = preamble_end;
4143 } 3884 }
4144 3885
4145 intptr_t i = 0; 3886 intptr_t i = 0;
4146 while (is_open() && (i < node->length())) { 3887 while (is_open() && (i < node->length())) {
4147 EffectGraphVisitor for_effect(owner()); 3888 EffectGraphVisitor for_effect(owner());
4148 node->NodeAt(i++)->Visit(&for_effect); 3889 node->NodeAt(i++)->Visit(&for_effect);
4149 Append(for_effect); 3890 Append(for_effect);
4150 if (!is_open()) { 3891 if (!is_open()) {
4151 // E.g., because of a JumpNode. 3892 // E.g., because of a JumpNode.
4152 break; 3893 break;
4153 } 3894 }
4154 } 3895 }
4155 3896
4156 // Continuation part: 3897 // Continuation part:
4157 // After generating the CFG for the body we can create the preamble 3898 // After generating the CFG for the body we can create the preamble
4158 // because we know exactly how many continuation states we need. 3899 // because we know exactly how many continuation states we need.
4159 if (is_top_level_sequence && 3900 if (is_top_level_sequence &&
4160 (function.IsAsyncClosure() || 3901 (function.IsAsyncClosure() || function.IsSyncGenClosure() ||
4161 function.IsSyncGenClosure() || 3902 function.IsAsyncGenClosure())) {
4162 function.IsAsyncGenClosure())) {
4163 ASSERT(preamble_start != NULL); 3903 ASSERT(preamble_start != NULL);
4164 // We are at the top level. Fetch the corresponding scope. 3904 // We are at the top level. Fetch the corresponding scope.
4165 LocalScope* top_scope = node->scope(); 3905 LocalScope* top_scope = node->scope();
4166 LocalVariable* jump_var = top_scope->LookupVariable( 3906 LocalVariable* jump_var =
4167 Symbols::AwaitJumpVar(), false); 3907 top_scope->LookupVariable(Symbols::AwaitJumpVar(), false);
4168 ASSERT(jump_var != NULL && jump_var->is_captured()); 3908 ASSERT(jump_var != NULL && jump_var->is_captured());
4169 Instruction* saved_entry = entry_; 3909 Instruction* saved_entry = entry_;
4170 Instruction* saved_exit = exit_; 3910 Instruction* saved_exit = exit_;
4171 entry_ = NULL; 3911 entry_ = NULL;
4172 exit_ = NULL; 3912 exit_ = NULL;
4173 3913
4174 LoadLocalNode* load_jump_count = 3914 LoadLocalNode* load_jump_count =
4175 new(Z) LoadLocalNode(node->token_pos(), jump_var); 3915 new (Z) LoadLocalNode(node->token_pos(), jump_var);
4176 ComparisonNode* check_jump_count; 3916 ComparisonNode* check_jump_count;
4177 const intptr_t num_await_states = owner()->await_joins()->length(); 3917 const intptr_t num_await_states = owner()->await_joins()->length();
4178 3918
4179 LocalVariable* old_context = top_scope->LookupVariable( 3919 LocalVariable* old_context =
4180 Symbols::AwaitContextVar(), false); 3920 top_scope->LookupVariable(Symbols::AwaitContextVar(), false);
4181 for (intptr_t i = 0; i < num_await_states; i++) { 3921 for (intptr_t i = 0; i < num_await_states; i++) {
4182 check_jump_count = new(Z) ComparisonNode( 3922 check_jump_count = new (Z)
4183 ST(node->token_pos()), 3923 ComparisonNode(ST(node->token_pos()), Token::kEQ, load_jump_count,
4184 Token::kEQ, 3924 new (Z) LiteralNode(ST(node->token_pos()),
4185 load_jump_count, 3925 Smi::ZoneHandle(Z, Smi::New(i))));
4186 new(Z) LiteralNode(
4187 ST(node->token_pos()), Smi::ZoneHandle(Z, Smi::New(i))));
4188 TestGraphVisitor for_test(owner(), ST(node->token_pos())); 3926 TestGraphVisitor for_test(owner(), ST(node->token_pos()));
4189 check_jump_count->Visit(&for_test); 3927 check_jump_count->Visit(&for_test);
4190 EffectGraphVisitor for_true(owner()); 3928 EffectGraphVisitor for_true(owner());
4191 EffectGraphVisitor for_false(owner()); 3929 EffectGraphVisitor for_false(owner());
4192 3930
4193 // Build async jump or sync yield jump. 3931 // Build async jump or sync yield jump.
4194 ASSERT(function.IsAsyncClosure() || 3932 ASSERT(function.IsAsyncClosure() || function.IsAsyncGenClosure() ||
4195 function.IsAsyncGenClosure() ||
4196 function.IsSyncGenClosure()); 3933 function.IsSyncGenClosure());
4197 3934
4198 // Restore the saved continuation context, i.e. the context that was 3935 // Restore the saved continuation context, i.e. the context that was
4199 // saved into :await_ctx_var before the closure suspended. 3936 // saved into :await_ctx_var before the closure suspended.
4200 for_true.BuildRestoreContext(*old_context, ST(node->token_pos())); 3937 for_true.BuildRestoreContext(*old_context, ST(node->token_pos()));
4201 3938
4202 // Goto saved join. 3939 // Goto saved join.
4203 for_true.Goto((*owner()->await_joins())[i]); 3940 for_true.Goto((*owner()->await_joins())[i]);
4204 3941
4205 Join(for_test, for_true, for_false); 3942 Join(for_test, for_true, for_false);
4206 if (i == 0) { 3943 if (i == 0) {
4207 // Manually link up the preamble start. 3944 // Manually link up the preamble start.
4208 preamble_start->previous()->set_next(for_test.entry()); 3945 preamble_start->previous()->set_next(for_test.entry());
4209 for_test.entry()->set_previous(preamble_start->previous()); 3946 for_test.entry()->set_previous(preamble_start->previous());
4210 } 3947 }
4211 if (i == (num_await_states - 1)) { 3948 if (i == (num_await_states - 1)) {
4212 // Link up preamble end. 3949 // Link up preamble end.
4213 if (exit_ == NULL) { 3950 if (exit_ == NULL) {
4214 exit_ = preamble_start; 3951 exit_ = preamble_start;
4215 } else { 3952 } else {
4216 exit_->LinkTo(preamble_start); 3953 exit_->LinkTo(preamble_start);
4217 } 3954 }
4218 } 3955 }
4219 } 3956 }
4220 entry_ = saved_entry; 3957 entry_ = saved_entry;
4221 exit_ = saved_exit; 3958 exit_ = saved_exit;
4222 } 3959 }
4223 3960
4224 if (is_open() && 3961 if (is_open() && (num_context_variables > 0) &&
4225 (num_context_variables > 0) &&
4226 (!is_top_level_sequence || HasContextScope())) { 3962 (!is_top_level_sequence || HasContextScope())) {
4227 UnchainContexts(1); 3963 UnchainContexts(1);
4228 } 3964 }
4229 3965
4230 // If this node sequence is labeled, a break out of the sequence will have 3966 // If this node sequence is labeled, a break out of the sequence will have
4231 // taken care of unchaining the context. 3967 // taken care of unchaining the context.
4232 if (nested_block.break_target() != NULL) { 3968 if (nested_block.break_target() != NULL) {
4233 if (is_open()) Goto(nested_block.break_target()); 3969 if (is_open()) Goto(nested_block.break_target());
4234 exit_ = nested_block.break_target(); 3970 exit_ = nested_block.break_target();
4235 } 3971 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
4272 ASSERT(try_handler_index != original_handler_index); 4008 ASSERT(try_handler_index != original_handler_index);
4273 owner()->set_try_index(try_handler_index); 4009 owner()->set_try_index(try_handler_index);
4274 4010
4275 // Preserve current context into local variable ':saved_try_context_var'. 4011 // Preserve current context into local variable ':saved_try_context_var'.
4276 BuildSaveContext(node->context_var(), ST(node->token_pos())); 4012 BuildSaveContext(node->context_var(), ST(node->token_pos()));
4277 4013
4278 EffectGraphVisitor for_try(owner()); 4014 EffectGraphVisitor for_try(owner());
4279 node->try_block()->Visit(&for_try); 4015 node->try_block()->Visit(&for_try);
4280 4016
4281 if (for_try.is_open()) { 4017 if (for_try.is_open()) {
4282 JoinEntryInstr* after_try = 4018 JoinEntryInstr* after_try = new (Z)
4283 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), 4019 JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index);
4284 original_handler_index);
4285 for_try.Goto(after_try); 4020 for_try.Goto(after_try);
4286 for_try.exit_ = after_try; 4021 for_try.exit_ = after_try;
4287 } 4022 }
4288 4023
4289 JoinEntryInstr* try_entry = 4024 JoinEntryInstr* try_entry =
4290 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index); 4025 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index);
4291 4026
4292 Goto(try_entry); 4027 Goto(try_entry);
4293 AppendFragment(try_entry, for_try); 4028 AppendFragment(try_entry, for_try);
4294 exit_ = for_try.exit_; 4029 exit_ = for_try.exit_;
4295 4030
4296 // We are done generating code for the try block. 4031 // We are done generating code for the try block.
4297 owner()->set_try_index(original_handler_index); 4032 owner()->set_try_index(original_handler_index);
4298 4033
4299 // If there is a finally block, it is the handler for code in the catch 4034 // If there is a finally block, it is the handler for code in the catch
4300 // block. 4035 // block.
4301 const intptr_t catch_handler_index = (finally_block == NULL) 4036 const intptr_t catch_handler_index = (finally_block == NULL)
4302 ? original_handler_index 4037 ? original_handler_index
4303 : catch_block->catch_handler_index(); 4038 : catch_block->catch_handler_index();
4304 4039
4305 const intptr_t prev_catch_try_index = owner()->catch_try_index(); 4040 const intptr_t prev_catch_try_index = owner()->catch_try_index();
4306 4041
4307 owner()->set_try_index(catch_handler_index); 4042 owner()->set_try_index(catch_handler_index);
4308 owner()->set_catch_try_index(try_handler_index); 4043 owner()->set_catch_try_index(try_handler_index);
4309 EffectGraphVisitor for_catch(owner()); 4044 EffectGraphVisitor for_catch(owner());
4310 catch_block->Visit(&for_catch); 4045 catch_block->Visit(&for_catch);
4311 owner()->set_catch_try_index(prev_catch_try_index); 4046 owner()->set_catch_try_index(prev_catch_try_index);
4312 4047
4313 // NOTE: The implicit variables ':saved_try_context_var', ':exception_var' 4048 // NOTE: The implicit variables ':saved_try_context_var', ':exception_var'
4314 // and ':stack_trace_var' can never be captured variables. 4049 // and ':stack_trace_var' can never be captured variables.
4315 ASSERT(!catch_block->context_var().is_captured()); 4050 ASSERT(!catch_block->context_var().is_captured());
4316 ASSERT(!catch_block->exception_var().is_captured()); 4051 ASSERT(!catch_block->exception_var().is_captured());
4317 ASSERT(!catch_block->stacktrace_var().is_captured()); 4052 ASSERT(!catch_block->stacktrace_var().is_captured());
4318 4053
4319 CatchBlockEntryInstr* catch_entry = 4054 CatchBlockEntryInstr* catch_entry = new (Z) CatchBlockEntryInstr(
4320 new(Z) CatchBlockEntryInstr(owner()->AllocateBlockId(), 4055 owner()->AllocateBlockId(), catch_handler_index, owner()->graph_entry(),
4321 catch_handler_index, 4056 catch_block->handler_types(), try_handler_index,
4322 owner()->graph_entry(), 4057 catch_block->exception_var(), catch_block->stacktrace_var(),
4323 catch_block->handler_types(), 4058 catch_block->needs_stacktrace(), Thread::Current()->GetNextDeoptId());
4324 try_handler_index,
4325 catch_block->exception_var(),
4326 catch_block->stacktrace_var(),
4327 catch_block->needs_stacktrace(),
4328 Thread::Current()->GetNextDeoptId());
4329 owner()->AddCatchEntry(catch_entry); 4059 owner()->AddCatchEntry(catch_entry);
4330 AppendFragment(catch_entry, for_catch); 4060 AppendFragment(catch_entry, for_catch);
4331 4061
4332 if (for_catch.is_open()) { 4062 if (for_catch.is_open()) {
4333 JoinEntryInstr* join = new(Z) JoinEntryInstr(owner()->AllocateBlockId(), 4063 JoinEntryInstr* join = new (Z)
4334 original_handler_index); 4064 JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index);
4335 for_catch.Goto(join); 4065 for_catch.Goto(join);
4336 if (is_open()) Goto(join); 4066 if (is_open()) Goto(join);
4337 exit_ = join; 4067 exit_ = join;
4338 } 4068 }
4339 4069
4340 if (finally_block != NULL) { 4070 if (finally_block != NULL) {
4341 ASSERT(node->rethrow_clause() != NULL); 4071 ASSERT(node->rethrow_clause() != NULL);
4342 // Create a handler for the code in the catch block, containing the 4072 // Create a handler for the code in the catch block, containing the
4343 // code in the finally block. 4073 // code in the finally block.
4344 owner()->set_try_index(original_handler_index); 4074 owner()->set_try_index(original_handler_index);
4345 EffectGraphVisitor for_finally(owner()); 4075 EffectGraphVisitor for_finally(owner());
4346 for_finally.BuildRestoreContext(catch_block->context_var(), 4076 for_finally.BuildRestoreContext(catch_block->context_var(),
4347 finally_block->token_pos()); 4077 finally_block->token_pos());
4348 4078
4349 node->rethrow_clause()->Visit(&for_finally); 4079 node->rethrow_clause()->Visit(&for_finally);
4350 if (for_finally.is_open()) { 4080 if (for_finally.is_open()) {
4351 // Rethrow the exception. Manually build the graph for rethrow. 4081 // Rethrow the exception. Manually build the graph for rethrow.
4352 Value* exception = for_finally.Bind(for_finally.BuildLoadLocal( 4082 Value* exception = for_finally.Bind(for_finally.BuildLoadLocal(
4353 catch_block->rethrow_exception_var(), finally_block->token_pos())); 4083 catch_block->rethrow_exception_var(), finally_block->token_pos()));
4354 for_finally.PushArgument(exception); 4084 for_finally.PushArgument(exception);
4355 Value* stacktrace = for_finally.Bind(for_finally.BuildLoadLocal( 4085 Value* stacktrace = for_finally.Bind(for_finally.BuildLoadLocal(
4356 catch_block->rethrow_stacktrace_var(), finally_block->token_pos())); 4086 catch_block->rethrow_stacktrace_var(), finally_block->token_pos()));
4357 for_finally.PushArgument(stacktrace); 4087 for_finally.PushArgument(stacktrace);
4358 for_finally.AddInstruction( 4088 for_finally.AddInstruction(
4359 new(Z) ReThrowInstr(catch_block->token_pos(), catch_handler_index)); 4089 new (Z) ReThrowInstr(catch_block->token_pos(), catch_handler_index));
4360 for_finally.CloseFragment(); 4090 for_finally.CloseFragment();
4361 } 4091 }
4362 ASSERT(!for_finally.is_open()); 4092 ASSERT(!for_finally.is_open());
4363 4093
4364 const Array& types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld)); 4094 const Array& types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld));
4365 types.SetAt(0, Object::dynamic_type()); 4095 types.SetAt(0, Object::dynamic_type());
4366 CatchBlockEntryInstr* finally_entry = 4096 CatchBlockEntryInstr* finally_entry = new (Z) CatchBlockEntryInstr(
4367 new(Z) CatchBlockEntryInstr(owner()->AllocateBlockId(), 4097 owner()->AllocateBlockId(), original_handler_index,
4368 original_handler_index, 4098 owner()->graph_entry(), types, catch_handler_index,
4369 owner()->graph_entry(), 4099 catch_block->exception_var(), catch_block->stacktrace_var(),
4370 types, 4100 catch_block->needs_stacktrace(), Thread::Current()->GetNextDeoptId());
4371 catch_handler_index,
4372 catch_block->exception_var(),
4373 catch_block->stacktrace_var(),
4374 catch_block->needs_stacktrace(),
4375 Thread::Current()->GetNextDeoptId());
4376 owner()->AddCatchEntry(finally_entry); 4101 owner()->AddCatchEntry(finally_entry);
4377 AppendFragment(finally_entry, for_finally); 4102 AppendFragment(finally_entry, for_finally);
4378 } 4103 }
4379 4104
4380 // Generate code for the finally block if one exists. 4105 // Generate code for the finally block if one exists.
4381 if ((finally_block != NULL) && is_open()) { 4106 if ((finally_block != NULL) && is_open()) {
4382 EffectGraphVisitor for_finally_block(owner()); 4107 EffectGraphVisitor for_finally_block(owner());
4383 finally_block->Visit(&for_finally_block); 4108 finally_block->Visit(&for_finally_block);
4384 Append(for_finally_block); 4109 Append(for_finally_block);
4385 } 4110 }
4386 } 4111 }
4387 4112
4388 4113
4389 // Looks up dynamic method noSuchMethod in target_class 4114 // Looks up dynamic method noSuchMethod in target_class
4390 // (including its super class chain) and builds a static call to it. 4115 // (including its super class chain) and builds a static call to it.
4391 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( 4116 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall(
4392 const Class& target_class, 4117 const Class& target_class,
4393 AstNode* receiver, 4118 AstNode* receiver,
4394 const String& method_name, 4119 const String& method_name,
4395 ArgumentListNode* method_arguments, 4120 ArgumentListNode* method_arguments,
4396 bool save_last_arg, 4121 bool save_last_arg,
4397 bool is_super_invocation) { 4122 bool is_super_invocation) {
4398 TokenPosition args_pos = method_arguments->token_pos(); 4123 TokenPosition args_pos = method_arguments->token_pos();
4399 LocalVariable* temp = NULL; 4124 LocalVariable* temp = NULL;
4400 if (save_last_arg) { 4125 if (save_last_arg) {
4401 temp = owner()->parsed_function().expression_temp_var(); 4126 temp = owner()->parsed_function().expression_temp_var();
4402 } 4127 }
4403 ArgumentListNode* args = 4128 ArgumentListNode* args = Parser::BuildNoSuchMethodArguments(
4404 Parser::BuildNoSuchMethodArguments(args_pos, 4129 args_pos, method_name, *method_arguments, temp, is_super_invocation);
4405 method_name,
4406 *method_arguments,
4407 temp,
4408 is_super_invocation);
4409 // Make sure we resolve to a compatible noSuchMethod, otherwise call 4130 // Make sure we resolve to a compatible noSuchMethod, otherwise call
4410 // noSuchMethod of class Object. 4131 // noSuchMethod of class Object.
4411 const int kNumArguments = 2; 4132 const int kNumArguments = 2;
4412 ArgumentsDescriptor args_desc( 4133 ArgumentsDescriptor args_desc(
4413 Array::ZoneHandle(Z, ArgumentsDescriptor::New(kNumArguments))); 4134 Array::ZoneHandle(Z, ArgumentsDescriptor::New(kNumArguments)));
4414 Function& no_such_method_func = Function::ZoneHandle(Z, 4135 Function& no_such_method_func = Function::ZoneHandle(
4415 Resolver::ResolveDynamicForReceiverClass(target_class, 4136 Z, Resolver::ResolveDynamicForReceiverClass(
4416 Symbols::NoSuchMethod(), 4137 target_class, Symbols::NoSuchMethod(), args_desc));
4417 args_desc));
4418 if (no_such_method_func.IsNull()) { 4138 if (no_such_method_func.IsNull()) {
4419 const Class& object_class = 4139 const Class& object_class =
4420 Class::ZoneHandle(Z, isolate()->object_store()->object_class()); 4140 Class::ZoneHandle(Z, isolate()->object_store()->object_class());
4421 no_such_method_func = 4141 no_such_method_func = Resolver::ResolveDynamicForReceiverClass(
4422 Resolver::ResolveDynamicForReceiverClass(object_class, 4142 object_class, Symbols::NoSuchMethod(), args_desc);
4423 Symbols::NoSuchMethod(),
4424 args_desc);
4425 } 4143 }
4426 // We are guaranteed to find noSuchMethod of class Object. 4144 // We are guaranteed to find noSuchMethod of class Object.
4427 ASSERT(!no_such_method_func.IsNull()); 4145 ASSERT(!no_such_method_func.IsNull());
4428 ZoneGrowableArray<PushArgumentInstr*>* push_arguments = 4146 ZoneGrowableArray<PushArgumentInstr*>* push_arguments =
4429 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); 4147 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
4430 BuildPushArguments(*args, push_arguments); 4148 BuildPushArguments(*args, push_arguments);
4431 return new(Z) StaticCallInstr(args_pos, 4149 return new (Z)
4432 no_such_method_func, 4150 StaticCallInstr(args_pos, no_such_method_func, Object::null_array(),
4433 Object::null_array(), 4151 push_arguments, owner()->ic_data_array());
4434 push_arguments,
4435 owner()->ic_data_array());
4436 } 4152 }
4437 4153
4438 4154
4439 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( 4155 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError(
4440 TokenPosition token_pos, 4156 TokenPosition token_pos,
4441 const Class& function_class, 4157 const Class& function_class,
4442 const String& function_name, 4158 const String& function_name,
4443 ArgumentListNode* function_arguments, 4159 ArgumentListNode* function_arguments,
4444 int invocation_type) { 4160 int invocation_type) {
4445 ZoneGrowableArray<PushArgumentInstr*>* arguments = 4161 ZoneGrowableArray<PushArgumentInstr*>* arguments =
4446 new(Z) ZoneGrowableArray<PushArgumentInstr*>(); 4162 new (Z) ZoneGrowableArray<PushArgumentInstr*>();
4447 // Object receiver, actually a class literal of the unresolved method's owner. 4163 // Object receiver, actually a class literal of the unresolved method's owner.
4448 AbstractType& type = Type::ZoneHandle( 4164 AbstractType& type = Type::ZoneHandle(
4449 Z, 4165 Z,
4450 Type::New(function_class, 4166 Type::New(function_class, TypeArguments::Handle(Z, TypeArguments::null()),
4451 TypeArguments::Handle(Z, TypeArguments::null()), 4167 token_pos, Heap::kOld));
4452 token_pos, 4168 type ^= ClassFinalizer::FinalizeType(function_class, type,
4453 Heap::kOld)); 4169 ClassFinalizer::kCanonicalize);
4454 type ^= ClassFinalizer::FinalizeType( 4170 Value* receiver_value = Bind(new (Z) ConstantInstr(type));
4455 function_class, type, ClassFinalizer::kCanonicalize);
4456 Value* receiver_value = Bind(new(Z) ConstantInstr(type));
4457 arguments->Add(PushArgument(receiver_value)); 4171 arguments->Add(PushArgument(receiver_value));
4458 // String memberName. 4172 // String memberName.
4459 const String& member_name = 4173 const String& member_name =
4460 String::ZoneHandle(Z, Symbols::New(T, function_name)); 4174 String::ZoneHandle(Z, Symbols::New(T, function_name));
4461 Value* member_name_value = Bind(new(Z) ConstantInstr(member_name)); 4175 Value* member_name_value = Bind(new (Z) ConstantInstr(member_name));
4462 arguments->Add(PushArgument(member_name_value)); 4176 arguments->Add(PushArgument(member_name_value));
4463 // Smi invocation_type. 4177 // Smi invocation_type.
4464 Value* invocation_type_value = Bind(new(Z) ConstantInstr( 4178 Value* invocation_type_value = Bind(
4465 Smi::ZoneHandle(Z, Smi::New(invocation_type)))); 4179 new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(invocation_type))));
4466 arguments->Add(PushArgument(invocation_type_value)); 4180 arguments->Add(PushArgument(invocation_type_value));
4467 // List arguments. 4181 // List arguments.
4468 if (function_arguments == NULL) { 4182 if (function_arguments == NULL) {
4469 Value* arguments_value = Bind( 4183 Value* arguments_value =
4470 new(Z) ConstantInstr(Array::ZoneHandle(Z, Array::null()))); 4184 Bind(new (Z) ConstantInstr(Array::ZoneHandle(Z, Array::null())));
4471 arguments->Add(PushArgument(arguments_value)); 4185 arguments->Add(PushArgument(arguments_value));
4472 } else { 4186 } else {
4473 ValueGraphVisitor array_val(owner()); 4187 ValueGraphVisitor array_val(owner());
4474 ArrayNode* array = 4188 ArrayNode* array =
4475 new(Z) ArrayNode(token_pos, Type::ZoneHandle(Z, Type::ArrayType()), 4189 new (Z) ArrayNode(token_pos, Type::ZoneHandle(Z, Type::ArrayType()),
4476 function_arguments->nodes()); 4190 function_arguments->nodes());
4477 array->Visit(&array_val); 4191 array->Visit(&array_val);
4478 Append(array_val); 4192 Append(array_val);
4479 arguments->Add(PushArgument(array_val.value())); 4193 arguments->Add(PushArgument(array_val.value()));
4480 } 4194 }
4481 // List argumentNames. 4195 // List argumentNames.
4482 ConstantInstr* cinstr = new(Z) ConstantInstr( 4196 ConstantInstr* cinstr = new (Z) ConstantInstr(
4483 (function_arguments == NULL) ? Array::ZoneHandle(Z, Array::null()) 4197 (function_arguments == NULL) ? Array::ZoneHandle(Z, Array::null())
4484 : function_arguments->names()); 4198 : function_arguments->names());
4485 Value* argument_names_value = Bind(cinstr); 4199 Value* argument_names_value = Bind(cinstr);
4486 arguments->Add(PushArgument(argument_names_value)); 4200 arguments->Add(PushArgument(argument_names_value));
4487 4201
4488 // List existingArgumentNames. 4202 // List existingArgumentNames.
4489 Value* existing_argument_names_value = 4203 Value* existing_argument_names_value =
4490 Bind(new(Z) ConstantInstr(Array::ZoneHandle(Z, Array::null()))); 4204 Bind(new (Z) ConstantInstr(Array::ZoneHandle(Z, Array::null())));
4491 arguments->Add(PushArgument(existing_argument_names_value)); 4205 arguments->Add(PushArgument(existing_argument_names_value));
4492 // Resolve and call NoSuchMethodError._throwNew. 4206 // Resolve and call NoSuchMethodError._throwNew.
4493 const Library& core_lib = Library::Handle(Z, Library::CoreLibrary()); 4207 const Library& core_lib = Library::Handle(Z, Library::CoreLibrary());
4494 const Class& cls = Class::Handle( 4208 const Class& cls =
4495 Z, core_lib.LookupClass(Symbols::NoSuchMethodError())); 4209 Class::Handle(Z, core_lib.LookupClass(Symbols::NoSuchMethodError()));
4496 ASSERT(!cls.IsNull()); 4210 ASSERT(!cls.IsNull());
4497 const Function& func = Function::ZoneHandle( 4211 const Function& func = Function::ZoneHandle(
4498 Z, 4212 Z, Resolver::ResolveStatic(
4499 Resolver::ResolveStatic(cls, 4213 cls, Library::PrivateCoreLibName(Symbols::ThrowNew()),
4500 Library::PrivateCoreLibName(Symbols::ThrowNew()), 4214 arguments->length(), Object::null_array()));
4501 arguments->length(),
4502 Object::null_array()));
4503 ASSERT(!func.IsNull()); 4215 ASSERT(!func.IsNull());
4504 return new(Z) StaticCallInstr(token_pos, 4216 return new (Z) StaticCallInstr(token_pos, func,
4505 func, 4217 Object::null_array(), // No names.
4506 Object::null_array(), // No names. 4218 arguments, owner()->ic_data_array());
4507 arguments,
4508 owner()->ic_data_array());
4509 } 4219 }
4510 4220
4511 4221
4512 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { 4222 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) {
4513 if (FLAG_support_debugger) { 4223 if (FLAG_support_debugger) {
4514 if (node->exception()->IsLiteralNode() || 4224 if (node->exception()->IsLiteralNode() ||
4515 node->exception()->IsLoadLocalNode() || 4225 node->exception()->IsLoadLocalNode() ||
4516 node->exception()->IsClosureNode()) { 4226 node->exception()->IsClosureNode()) {
4517 AddInstruction(new(Z) DebugStepCheckInstr( 4227 AddInstruction(new (Z) DebugStepCheckInstr(
4518 node->token_pos(), RawPcDescriptors::kRuntimeCall)); 4228 node->token_pos(), RawPcDescriptors::kRuntimeCall));
4519 } 4229 }
4520 } 4230 }
4521 ValueGraphVisitor for_exception(owner()); 4231 ValueGraphVisitor for_exception(owner());
4522 node->exception()->Visit(&for_exception); 4232 node->exception()->Visit(&for_exception);
4523 Append(for_exception); 4233 Append(for_exception);
4524 PushArgument(for_exception.value()); 4234 PushArgument(for_exception.value());
4525 Instruction* instr = NULL; 4235 Instruction* instr = NULL;
4526 if (node->stacktrace() == NULL) { 4236 if (node->stacktrace() == NULL) {
4527 instr = new(Z) ThrowInstr(node->token_pos()); 4237 instr = new (Z) ThrowInstr(node->token_pos());
4528 } else { 4238 } else {
4529 ValueGraphVisitor for_stack_trace(owner()); 4239 ValueGraphVisitor for_stack_trace(owner());
4530 node->stacktrace()->Visit(&for_stack_trace); 4240 node->stacktrace()->Visit(&for_stack_trace);
4531 Append(for_stack_trace); 4241 Append(for_stack_trace);
4532 PushArgument(for_stack_trace.value()); 4242 PushArgument(for_stack_trace.value());
4533 instr = new(Z) ReThrowInstr(node->token_pos(), owner()->catch_try_index()); 4243 instr = new (Z) ReThrowInstr(node->token_pos(), owner()->catch_try_index());
4534 } 4244 }
4535 AddInstruction(instr); 4245 AddInstruction(instr);
4536 } 4246 }
4537 4247
4538 4248
4539 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { 4249 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) {
4540 BuildThrowNode(node); 4250 BuildThrowNode(node);
4541 CloseFragment(); 4251 CloseFragment();
4542 } 4252 }
4543 4253
4544 4254
4545 // A throw cannot be part of an expression, however, the parser may replace 4255 // A throw cannot be part of an expression, however, the parser may replace
4546 // certain expression nodes with a throw. In that case generate a literal null 4256 // certain expression nodes with a throw. In that case generate a literal null
4547 // so that the fragment is not closed in the middle of an expression. 4257 // so that the fragment is not closed in the middle of an expression.
4548 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { 4258 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) {
4549 BuildThrowNode(node); 4259 BuildThrowNode(node);
4550 ReturnDefinition(new(Z) ConstantInstr( 4260 ReturnDefinition(
4551 Instance::ZoneHandle(Z, Instance::null()))); 4261 new (Z) ConstantInstr(Instance::ZoneHandle(Z, Instance::null())));
4552 } 4262 }
4553 4263
4554 4264
4555 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { 4265 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
4556 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)"); 4266 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)");
4557 const intptr_t try_index = owner()->try_index(); 4267 const intptr_t try_index = owner()->try_index();
4558 if (try_index >= 0) { 4268 if (try_index >= 0) {
4559 // We are about to generate code for an inlined finally block. Exceptions 4269 // We are about to generate code for an inlined finally block. Exceptions
4560 // thrown in this block of code should be treated as though they are 4270 // thrown in this block of code should be treated as though they are
4561 // thrown not from the current try block but the outer try block if any. 4271 // thrown not from the current try block but the outer try block if any.
4562 intptr_t outer_try_index = node->try_index(); 4272 intptr_t outer_try_index = node->try_index();
4563 owner()->set_try_index(outer_try_index); 4273 owner()->set_try_index(outer_try_index);
4564 } 4274 }
4565 4275
4566 // Note: do not restore the saved_try_context here since the inlined 4276 // Note: do not restore the saved_try_context here since the inlined
4567 // code is not reached via an exception handler, therefore the context is 4277 // code is not reached via an exception handler, therefore the context is
4568 // always properly set on entry. In other words, the inlined finally clause is 4278 // always properly set on entry. In other words, the inlined finally clause is
4569 // never the target of a long jump that would find an uninitialized current 4279 // never the target of a long jump that would find an uninitialized current
4570 // context variable. 4280 // context variable.
4571 4281
4572 JoinEntryInstr* finally_entry = 4282 JoinEntryInstr* finally_entry =
4573 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 4283 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
4574 EffectGraphVisitor for_finally_block(owner()); 4284 EffectGraphVisitor for_finally_block(owner());
4575 for_finally_block.AdjustContextLevel(node->finally_block()->scope()); 4285 for_finally_block.AdjustContextLevel(node->finally_block()->scope());
4576 node->finally_block()->Visit(&for_finally_block); 4286 node->finally_block()->Visit(&for_finally_block);
4577 4287
4578 if (try_index >= 0) { 4288 if (try_index >= 0) {
4579 owner()->set_try_index(try_index); 4289 owner()->set_try_index(try_index);
4580 } 4290 }
4581 4291
4582 if (for_finally_block.is_open()) { 4292 if (for_finally_block.is_open()) {
4583 JoinEntryInstr* after_finally = 4293 JoinEntryInstr* after_finally = new (Z)
4584 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); 4294 JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
4585 for_finally_block.Goto(after_finally); 4295 for_finally_block.Goto(after_finally);
4586 for_finally_block.exit_ = after_finally; 4296 for_finally_block.exit_ = after_finally;
4587 } 4297 }
4588 4298
4589 Goto(finally_entry); 4299 Goto(finally_entry);
4590 AppendFragment(finally_entry, for_finally_block); 4300 AppendFragment(finally_entry, for_finally_block);
4591 exit_ = for_finally_block.exit_; 4301 exit_ = for_finally_block.exit_;
4592 } 4302 }
4593 4303
4594 4304
4595 void EffectGraphVisitor::VisitStopNode(StopNode* node) { 4305 void EffectGraphVisitor::VisitStopNode(StopNode* node) {
4596 AddInstruction(new(Z) StopInstr(node->message())); 4306 AddInstruction(new (Z) StopInstr(node->message()));
4597 } 4307 }
4598 4308
4599 4309
4600 FlowGraph* FlowGraphBuilder::BuildGraph() { 4310 FlowGraph* FlowGraphBuilder::BuildGraph() {
4601 VMTagScope tagScope(thread(), 4311 VMTagScope tagScope(thread(), VMTag::kCompileFlowGraphBuilderTagId,
4602 VMTag::kCompileFlowGraphBuilderTagId,
4603 FLAG_profile_vm); 4312 FLAG_profile_vm);
4604 if (FLAG_support_ast_printer && FLAG_print_ast) { 4313 if (FLAG_support_ast_printer && FLAG_print_ast) {
4605 // Print the function ast before IL generation. 4314 // Print the function ast before IL generation.
4606 AstPrinter ast_printer; 4315 AstPrinter ast_printer;
4607 ast_printer.PrintFunctionNodes(parsed_function()); 4316 ast_printer.PrintFunctionNodes(parsed_function());
4608 } 4317 }
4609 if (FLAG_support_ast_printer && FLAG_print_scopes) { 4318 if (FLAG_support_ast_printer && FLAG_print_scopes) {
4610 AstPrinter ast_printer; 4319 AstPrinter ast_printer;
4611 ast_printer.PrintFunctionScope(parsed_function()); 4320 ast_printer.PrintFunctionScope(parsed_function());
4612 } 4321 }
4613 TargetEntryInstr* normal_entry = 4322 TargetEntryInstr* normal_entry = new (Z)
4614 new(Z) TargetEntryInstr(AllocateBlockId(), 4323 TargetEntryInstr(AllocateBlockId(), CatchClauseNode::kInvalidTryIndex);
4615 CatchClauseNode::kInvalidTryIndex);
4616 graph_entry_ = 4324 graph_entry_ =
4617 new(Z) GraphEntryInstr(parsed_function(), normal_entry, osr_id_); 4325 new (Z) GraphEntryInstr(parsed_function(), normal_entry, osr_id_);
4618 EffectGraphVisitor for_effect(this); 4326 EffectGraphVisitor for_effect(this);
4619 parsed_function().node_sequence()->Visit(&for_effect); 4327 parsed_function().node_sequence()->Visit(&for_effect);
4620 AppendFragment(normal_entry, for_effect); 4328 AppendFragment(normal_entry, for_effect);
4621 // Check that the graph is properly terminated. 4329 // Check that the graph is properly terminated.
4622 ASSERT(!for_effect.is_open()); 4330 ASSERT(!for_effect.is_open());
4623 4331
4624 // When compiling for OSR, use a depth first search to prune instructions 4332 // When compiling for OSR, use a depth first search to prune instructions
4625 // unreachable from the OSR entry. Catch entries are always considered 4333 // unreachable from the OSR entry. Catch entries are always considered
4626 // reachable, even if they become unreachable after OSR. 4334 // reachable, even if they become unreachable after OSR.
4627 if (osr_id_ != Compiler::kNoOSRDeoptId) { 4335 if (osr_id_ != Compiler::kNoOSRDeoptId) {
4628 PruneUnreachable(); 4336 PruneUnreachable();
4629 } 4337 }
4630 4338
4631 FlowGraph* graph = 4339 FlowGraph* graph =
4632 new(Z) FlowGraph(parsed_function(), graph_entry_, last_used_block_id_); 4340 new (Z) FlowGraph(parsed_function(), graph_entry_, last_used_block_id_);
4633 return graph; 4341 return graph;
4634 } 4342 }
4635 4343
4636 4344
4637 void FlowGraphBuilder::PruneUnreachable() { 4345 void FlowGraphBuilder::PruneUnreachable() {
4638 ASSERT(osr_id_ != Compiler::kNoOSRDeoptId); 4346 ASSERT(osr_id_ != Compiler::kNoOSRDeoptId);
4639 BitVector* block_marks = new(Z) BitVector(Z, last_used_block_id_ + 1); 4347 BitVector* block_marks = new (Z) BitVector(Z, last_used_block_id_ + 1);
4640 bool found = graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, 4348 bool found =
4641 block_marks); 4349 graph_entry_->PruneUnreachable(graph_entry_, NULL, osr_id_, block_marks);
4642 ASSERT(found); 4350 ASSERT(found);
4643 } 4351 }
4644 4352
4645 4353
4646 void FlowGraphBuilder::Bailout(const char* reason) const { 4354 void FlowGraphBuilder::Bailout(const char* reason) const {
4647 parsed_function_.Bailout("FlowGraphBuilder", reason); 4355 parsed_function_.Bailout("FlowGraphBuilder", reason);
4648 } 4356 }
4649 4357
4650 } // namespace dart 4358 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_builder_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698