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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« 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/class_finalizer.h"
10 #include "vm/compiler.h" 11 #include "vm/compiler.h"
11 #include "vm/class_finalizer.h"
12 #include "vm/exceptions.h" 12 #include "vm/exceptions.h"
13 #include "vm/flags.h" 13 #include "vm/flags.h"
14 #include "vm/flow_graph.h" 14 #include "vm/flow_graph.h"
15 #include "vm/flow_graph_compiler.h" 15 #include "vm/flow_graph_compiler.h"
16 #include "vm/heap.h" 16 #include "vm/heap.h"
17 #include "vm/il_printer.h" 17 #include "vm/il_printer.h"
18 #include "vm/intermediate_language.h" 18 #include "vm/intermediate_language.h"
19 #include "vm/isolate.h" 19 #include "vm/isolate.h"
20 #include "vm/object.h" 20 #include "vm/object.h"
21 #include "vm/object_store.h" 21 #include "vm/object_store.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 uword FlowGraphBuilder::FindDoubleConstant(double value) { 68 uword FlowGraphBuilder::FindDoubleConstant(double value) {
69 intptr_t len = sizeof(kCommonDoubleConstants) / sizeof(double); // NOLINT 69 intptr_t len = sizeof(kCommonDoubleConstants) / sizeof(double); // NOLINT
70 for (intptr_t i = 0; i < len; i++) { 70 for (intptr_t i = 0; i < len; i++) {
71 if (Utils::DoublesBitEqual(value, kCommonDoubleConstants[i])) { 71 if (Utils::DoublesBitEqual(value, kCommonDoubleConstants[i])) {
72 return reinterpret_cast<uword>(&kCommonDoubleConstants[i]); 72 return reinterpret_cast<uword>(&kCommonDoubleConstants[i]);
73 } 73 }
74 } 74 }
75 return 0; 75 return 0;
76 } 76 }
77 77
78
79 #define RECOGNIZE_FACTORY(symbol, class_name, constructor_name, cid, fp) \ 78 #define RECOGNIZE_FACTORY(symbol, class_name, constructor_name, cid, fp) \
80 {Symbols::k##symbol##Id, cid, fp, #symbol ", " #cid}, // NOLINT 79 {Symbols::k##symbol##Id, cid, fp, #symbol ", " #cid}, // NOLINT
81 80
82 static struct { 81 static struct {
83 intptr_t symbol_id; 82 intptr_t symbol_id;
84 intptr_t cid; 83 intptr_t cid;
85 intptr_t finger_print; 84 intptr_t finger_print;
86 const char* name; 85 const char* name;
87 } factory_recognizer_list[] = {RECOGNIZED_LIST_FACTORY_LIST(RECOGNIZE_FACTORY){ 86 } factory_recognizer_list[] = {RECOGNIZED_LIST_FACTORY_LIST(RECOGNIZE_FACTORY){
88 Symbols::kIllegal, -1, -1, NULL}}; 87 Symbols::kIllegal, -1, -1, NULL}};
(...skipping 11 matching lines...) Expand all
100 factory_recognizer_list[i].symbol_id != Symbols::kIllegal; i++) { 99 factory_recognizer_list[i].symbol_id != Symbols::kIllegal; i++) {
101 if (String::EqualsIgnoringPrivateKey( 100 if (String::EqualsIgnoringPrivateKey(
102 factory_name, 101 factory_name,
103 Symbols::Symbol(factory_recognizer_list[i].symbol_id))) { 102 Symbols::Symbol(factory_recognizer_list[i].symbol_id))) {
104 return factory_recognizer_list[i].cid; 103 return factory_recognizer_list[i].cid;
105 } 104 }
106 } 105 }
107 return kDynamicCid; 106 return kDynamicCid;
108 } 107 }
109 108
110
111 // Base class for a stack of enclosing statements of interest (e.g., 109 // Base class for a stack of enclosing statements of interest (e.g.,
112 // blocks (breakable) and loops (continuable)). 110 // blocks (breakable) and loops (continuable)).
113 class NestedStatement : public ValueObject { 111 class NestedStatement : public ValueObject {
114 public: 112 public:
115 FlowGraphBuilder* owner() const { return owner_; } 113 FlowGraphBuilder* owner() const { return owner_; }
116 const SourceLabel* label() const { return label_; } 114 const SourceLabel* label() const { return label_; }
117 NestedStatement* outer() const { return outer_; } 115 NestedStatement* outer() const { return outer_; }
118 JoinEntryInstr* break_target() const { return break_target_; } 116 JoinEntryInstr* break_target() const { return break_target_; }
119 117
120 virtual intptr_t ContextLevel() const; 118 virtual intptr_t ContextLevel() const;
(...skipping 23 matching lines...) Expand all
144 142
145 private: 143 private:
146 FlowGraphBuilder* owner_; 144 FlowGraphBuilder* owner_;
147 const SourceLabel* label_; 145 const SourceLabel* label_;
148 NestedStatement* outer_; 146 NestedStatement* outer_;
149 147
150 JoinEntryInstr* break_target_; 148 JoinEntryInstr* break_target_;
151 const intptr_t try_index_; 149 const intptr_t try_index_;
152 }; 150 };
153 151
154
155 intptr_t NestedStatement::ContextLevel() const { 152 intptr_t NestedStatement::ContextLevel() const {
156 // Context level is determined by the innermost nested statement having one. 153 // Context level is determined by the innermost nested statement having one.
157 return (outer() == NULL) ? 0 : outer()->ContextLevel(); 154 return (outer() == NULL) ? 0 : outer()->ContextLevel();
158 } 155 }
159 156
160
161 void NestedStatement::AdjustContextLevel(intptr_t context_level) { 157 void NestedStatement::AdjustContextLevel(intptr_t context_level) {
162 // There must be a NestedContextAdjustment on the nesting stack. 158 // There must be a NestedContextAdjustment on the nesting stack.
163 ASSERT(outer() != NULL); 159 ASSERT(outer() != NULL);
164 outer()->AdjustContextLevel(context_level); 160 outer()->AdjustContextLevel(context_level);
165 } 161 }
166 162
167
168 intptr_t FlowGraphBuilder::GetNextDeoptId() const { 163 intptr_t FlowGraphBuilder::GetNextDeoptId() const {
169 intptr_t deopt_id = thread()->GetNextDeoptId(); 164 intptr_t deopt_id = thread()->GetNextDeoptId();
170 if (context_level_array_ != NULL) { 165 if (context_level_array_ != NULL) {
171 intptr_t level = context_level(); 166 intptr_t level = context_level();
172 context_level_array_->Add(deopt_id); 167 context_level_array_->Add(deopt_id);
173 context_level_array_->Add(level); 168 context_level_array_->Add(level);
174 } 169 }
175 return deopt_id; 170 return deopt_id;
176 } 171 }
177 172
178
179 intptr_t FlowGraphBuilder::context_level() const { 173 intptr_t FlowGraphBuilder::context_level() const {
180 return (nesting_stack() == NULL) ? 0 : nesting_stack()->ContextLevel(); 174 return (nesting_stack() == NULL) ? 0 : nesting_stack()->ContextLevel();
181 } 175 }
182 176
183
184 JoinEntryInstr* NestedStatement::BreakTargetFor(SourceLabel* label) { 177 JoinEntryInstr* NestedStatement::BreakTargetFor(SourceLabel* label) {
185 if (label != label_) return NULL; 178 if (label != label_) return NULL;
186 if (break_target_ == NULL) { 179 if (break_target_ == NULL) {
187 break_target_ = new (owner()->zone()) JoinEntryInstr( 180 break_target_ = new (owner()->zone()) JoinEntryInstr(
188 owner()->AllocateBlockId(), try_index(), owner()->GetNextDeoptId()); 181 owner()->AllocateBlockId(), try_index(), owner()->GetNextDeoptId());
189 } 182 }
190 return break_target_; 183 return break_target_;
191 } 184 }
192 185
193
194 JoinEntryInstr* NestedStatement::ContinueTargetFor(SourceLabel* label) { 186 JoinEntryInstr* NestedStatement::ContinueTargetFor(SourceLabel* label) {
195 return NULL; 187 return NULL;
196 } 188 }
197 189
198
199 // A nested statement that has its own context level. 190 // A nested statement that has its own context level.
200 class NestedBlock : public NestedStatement { 191 class NestedBlock : public NestedStatement {
201 public: 192 public:
202 NestedBlock(FlowGraphBuilder* owner, SequenceNode* node) 193 NestedBlock(FlowGraphBuilder* owner, SequenceNode* node)
203 : NestedStatement(owner, node->label()), scope_(node->scope()) {} 194 : NestedStatement(owner, node->label()), scope_(node->scope()) {}
204 195
205 virtual intptr_t ContextLevel() const; 196 virtual intptr_t ContextLevel() const;
206 197
207 private: 198 private:
208 LocalScope* scope_; 199 LocalScope* scope_;
209 }; 200 };
210 201
211
212 intptr_t NestedBlock::ContextLevel() const { 202 intptr_t NestedBlock::ContextLevel() const {
213 return ((scope_ == NULL) || (scope_->num_context_variables() == 0)) 203 return ((scope_ == NULL) || (scope_->num_context_variables() == 0))
214 ? NestedStatement::ContextLevel() 204 ? NestedStatement::ContextLevel()
215 : scope_->context_level(); 205 : scope_->context_level();
216 } 206 }
217 207
218
219 // A nested statement reflecting a context level adjustment. 208 // A nested statement reflecting a context level adjustment.
220 class NestedContextAdjustment : public NestedStatement { 209 class NestedContextAdjustment : public NestedStatement {
221 public: 210 public:
222 NestedContextAdjustment(FlowGraphBuilder* owner, intptr_t context_level) 211 NestedContextAdjustment(FlowGraphBuilder* owner, intptr_t context_level)
223 : NestedStatement(owner, NULL), context_level_(context_level) {} 212 : NestedStatement(owner, NULL), context_level_(context_level) {}
224 213
225 virtual intptr_t ContextLevel() const { return context_level_; } 214 virtual intptr_t ContextLevel() const { return context_level_; }
226 215
227 virtual void AdjustContextLevel(intptr_t context_level) { 216 virtual void AdjustContextLevel(intptr_t context_level) {
228 ASSERT(context_level <= context_level_); 217 ASSERT(context_level <= context_level_);
229 context_level_ = context_level; 218 context_level_ = context_level;
230 } 219 }
231 220
232 private: 221 private:
233 intptr_t context_level_; 222 intptr_t context_level_;
234 }; 223 };
235 224
236
237 // A nested statement that can be the target of a continue as well as a 225 // A nested statement that can be the target of a continue as well as a
238 // break. 226 // break.
239 class NestedLoop : public NestedStatement { 227 class NestedLoop : public NestedStatement {
240 public: 228 public:
241 NestedLoop(FlowGraphBuilder* owner, SourceLabel* label) 229 NestedLoop(FlowGraphBuilder* owner, SourceLabel* label)
242 : NestedStatement(owner, label), continue_target_(NULL) { 230 : NestedStatement(owner, label), continue_target_(NULL) {
243 owner->IncrementLoopDepth(); 231 owner->IncrementLoopDepth();
244 } 232 }
245 233
246 virtual ~NestedLoop() { owner()->DecrementLoopDepth(); } 234 virtual ~NestedLoop() { owner()->DecrementLoopDepth(); }
247 235
248 JoinEntryInstr* continue_target() const { return continue_target_; } 236 JoinEntryInstr* continue_target() const { return continue_target_; }
249 237
250 virtual JoinEntryInstr* ContinueTargetFor(SourceLabel* label); 238 virtual JoinEntryInstr* ContinueTargetFor(SourceLabel* label);
251 239
252 private: 240 private:
253 JoinEntryInstr* continue_target_; 241 JoinEntryInstr* continue_target_;
254 }; 242 };
255 243
256
257 JoinEntryInstr* NestedLoop::ContinueTargetFor(SourceLabel* label) { 244 JoinEntryInstr* NestedLoop::ContinueTargetFor(SourceLabel* label) {
258 if (label != this->label()) return NULL; 245 if (label != this->label()) return NULL;
259 if (continue_target_ == NULL) { 246 if (continue_target_ == NULL) {
260 continue_target_ = new (owner()->zone()) JoinEntryInstr( 247 continue_target_ = new (owner()->zone()) JoinEntryInstr(
261 owner()->AllocateBlockId(), try_index(), owner()->GetNextDeoptId()); 248 owner()->AllocateBlockId(), try_index(), owner()->GetNextDeoptId());
262 } 249 }
263 return continue_target_; 250 return continue_target_;
264 } 251 }
265 252
266
267 // A nested switch which can be the target of a break if labeled, and whose 253 // A nested switch which can be the target of a break if labeled, and whose
268 // cases can be the targets of continues. 254 // cases can be the targets of continues.
269 class NestedSwitch : public NestedStatement { 255 class NestedSwitch : public NestedStatement {
270 public: 256 public:
271 NestedSwitch(FlowGraphBuilder* owner, SwitchNode* node); 257 NestedSwitch(FlowGraphBuilder* owner, SwitchNode* node);
272 258
273 virtual JoinEntryInstr* ContinueTargetFor(SourceLabel* label); 259 virtual JoinEntryInstr* ContinueTargetFor(SourceLabel* label);
274 260
275 private: 261 private:
276 GrowableArray<SourceLabel*> case_labels_; 262 GrowableArray<SourceLabel*> case_labels_;
277 GrowableArray<JoinEntryInstr*> case_targets_; 263 GrowableArray<JoinEntryInstr*> case_targets_;
278 }; 264 };
279 265
280
281 NestedSwitch::NestedSwitch(FlowGraphBuilder* owner, SwitchNode* node) 266 NestedSwitch::NestedSwitch(FlowGraphBuilder* owner, SwitchNode* node)
282 : NestedStatement(owner, node->label()), 267 : NestedStatement(owner, node->label()),
283 case_labels_(node->body()->length()), 268 case_labels_(node->body()->length()),
284 case_targets_(node->body()->length()) { 269 case_targets_(node->body()->length()) {
285 SequenceNode* body = node->body(); 270 SequenceNode* body = node->body();
286 for (intptr_t i = 0; i < body->length(); ++i) { 271 for (intptr_t i = 0; i < body->length(); ++i) {
287 CaseNode* case_node = body->NodeAt(i)->AsCaseNode(); 272 CaseNode* case_node = body->NodeAt(i)->AsCaseNode();
288 if (case_node != NULL) { 273 if (case_node != NULL) {
289 case_labels_.Add(case_node->label()); 274 case_labels_.Add(case_node->label());
290 case_targets_.Add(NULL); 275 case_targets_.Add(NULL);
291 } 276 }
292 } 277 }
293 } 278 }
294 279
295
296 JoinEntryInstr* NestedSwitch::ContinueTargetFor(SourceLabel* label) { 280 JoinEntryInstr* NestedSwitch::ContinueTargetFor(SourceLabel* label) {
297 // Allocate a join for a case clause that matches the label. This block 281 // Allocate a join for a case clause that matches the label. This block
298 // is not necessarily targeted by a continue, but we always use a join in 282 // is not necessarily targeted by a continue, but we always use a join in
299 // the graph anyway. 283 // the graph anyway.
300 for (intptr_t i = 0; i < case_labels_.length(); ++i) { 284 for (intptr_t i = 0; i < case_labels_.length(); ++i) {
301 if (label != case_labels_[i]) continue; 285 if (label != case_labels_[i]) continue;
302 if (case_targets_[i] == NULL) { 286 if (case_targets_[i] == NULL) {
303 case_targets_[i] = new (owner()->zone()) JoinEntryInstr( 287 case_targets_[i] = new (owner()->zone()) JoinEntryInstr(
304 owner()->AllocateBlockId(), try_index(), owner()->GetNextDeoptId()); 288 owner()->AllocateBlockId(), try_index(), owner()->GetNextDeoptId());
305 } 289 }
306 return case_targets_[i]; 290 return case_targets_[i];
307 } 291 }
308 return NULL; 292 return NULL;
309 } 293 }
310 294
311
312 FlowGraphBuilder::FlowGraphBuilder( 295 FlowGraphBuilder::FlowGraphBuilder(
313 const ParsedFunction& parsed_function, 296 const ParsedFunction& parsed_function,
314 const ZoneGrowableArray<const ICData*>& ic_data_array, 297 const ZoneGrowableArray<const ICData*>& ic_data_array,
315 ZoneGrowableArray<intptr_t>* context_level_array, 298 ZoneGrowableArray<intptr_t>* context_level_array,
316 InlineExitCollector* exit_collector, 299 InlineExitCollector* exit_collector,
317 intptr_t osr_id) 300 intptr_t osr_id)
318 : parsed_function_(parsed_function), 301 : parsed_function_(parsed_function),
319 ic_data_array_(ic_data_array), 302 ic_data_array_(ic_data_array),
320 context_level_array_(context_level_array), 303 context_level_array_(context_level_array),
321 num_copied_params_(parsed_function.num_copied_params()), 304 num_copied_params_(parsed_function.num_copied_params()),
(...skipping 10 matching lines...) Expand all
332 loop_depth_(0), 315 loop_depth_(0),
333 graph_entry_(NULL), 316 graph_entry_(NULL),
334 temp_count_(0), 317 temp_count_(0),
335 args_pushed_(0), 318 args_pushed_(0),
336 nesting_stack_(NULL), 319 nesting_stack_(NULL),
337 osr_id_(osr_id), 320 osr_id_(osr_id),
338 jump_count_(0), 321 jump_count_(0),
339 await_joins_(new (Z) ZoneGrowableArray<JoinEntryInstr*>()), 322 await_joins_(new (Z) ZoneGrowableArray<JoinEntryInstr*>()),
340 await_token_positions_(new (Z) ZoneGrowableArray<TokenPosition>()) {} 323 await_token_positions_(new (Z) ZoneGrowableArray<TokenPosition>()) {}
341 324
342
343 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) { 325 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) {
344 graph_entry_->AddCatchEntry(entry); 326 graph_entry_->AddCatchEntry(entry);
345 } 327 }
346 328
347
348 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) { 329 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) {
349 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1); 330 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1);
350 ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id()); 331 ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id());
351 ASSERT(callee_graph->max_virtual_register_number() > 332 ASSERT(callee_graph->max_virtual_register_number() >
352 caller_graph_->max_virtual_register_number()); 333 caller_graph_->max_virtual_register_number());
353 334
354 // Adjust the caller's maximum block id and current SSA temp index. 335 // Adjust the caller's maximum block id and current SSA temp index.
355 caller_graph_->set_max_block_id(callee_graph->max_block_id()); 336 caller_graph_->set_max_block_id(callee_graph->max_block_id());
356 caller_graph_->set_current_ssa_temp_index( 337 caller_graph_->set_current_ssa_temp_index(
357 callee_graph->max_virtual_register_number()); 338 callee_graph->max_virtual_register_number());
(...skipping 24 matching lines...) Expand all
382 } 363 }
383 } 364 }
384 if (instr->IsGoto()) { 365 if (instr->IsGoto()) {
385 instr->AsGoto()->adjust_edge_weight(scale_factor); 366 instr->AsGoto()->adjust_edge_weight(scale_factor);
386 } 367 }
387 } 368 }
388 369
389 RemoveUnreachableExits(callee_graph); 370 RemoveUnreachableExits(callee_graph);
390 } 371 }
391 372
392
393 void InlineExitCollector::AddExit(ReturnInstr* exit) { 373 void InlineExitCollector::AddExit(ReturnInstr* exit) {
394 Data data = {NULL, exit}; 374 Data data = {NULL, exit};
395 exits_.Add(data); 375 exits_.Add(data);
396 } 376 }
397 377
398
399 void InlineExitCollector::Union(const InlineExitCollector* other) { 378 void InlineExitCollector::Union(const InlineExitCollector* other) {
400 // It doesn't make sense to combine different calls or calls from 379 // It doesn't make sense to combine different calls or calls from
401 // different graphs. 380 // different graphs.
402 ASSERT(caller_graph_ == other->caller_graph_); 381 ASSERT(caller_graph_ == other->caller_graph_);
403 ASSERT(call_ == other->call_); 382 ASSERT(call_ == other->call_);
404 exits_.AddArray(other->exits_); 383 exits_.AddArray(other->exits_);
405 } 384 }
406 385
407
408 int InlineExitCollector::LowestBlockIdFirst(const Data* a, const Data* b) { 386 int InlineExitCollector::LowestBlockIdFirst(const Data* a, const Data* b) {
409 return (a->exit_block->block_id() - b->exit_block->block_id()); 387 return (a->exit_block->block_id() - b->exit_block->block_id());
410 } 388 }
411 389
412
413 void InlineExitCollector::RemoveUnreachableExits(FlowGraph* callee_graph) { 390 void InlineExitCollector::RemoveUnreachableExits(FlowGraph* callee_graph) {
414 const GrowableArray<BlockEntryInstr*>& postorder = callee_graph->postorder(); 391 const GrowableArray<BlockEntryInstr*>& postorder = callee_graph->postorder();
415 int j = 0; 392 int j = 0;
416 for (int i = 0; i < exits_.length(); ++i) { 393 for (int i = 0; i < exits_.length(); ++i) {
417 BlockEntryInstr* block = exits_[i].exit_return->GetBlock(); 394 BlockEntryInstr* block = exits_[i].exit_return->GetBlock();
418 if ((block != NULL) && (0 <= block->postorder_number()) && 395 if ((block != NULL) && (0 <= block->postorder_number()) &&
419 (block->postorder_number() < postorder.length()) && 396 (block->postorder_number() < postorder.length()) &&
420 (postorder[block->postorder_number()] == block)) { 397 (postorder[block->postorder_number()] == block)) {
421 if (i != j) { 398 if (i != j) {
422 exits_[j] = exits_[i]; 399 exits_[j] = exits_[i];
423 } 400 }
424 j++; 401 j++;
425 } 402 }
426 } 403 }
427 exits_.TruncateTo(j); 404 exits_.TruncateTo(j);
428 } 405 }
429 406
430
431 void InlineExitCollector::SortExits() { 407 void InlineExitCollector::SortExits() {
432 // Assign block entries here because we did not necessarily know them when 408 // Assign block entries here because we did not necessarily know them when
433 // the return exit was added to the array. 409 // the return exit was added to the array.
434 for (int i = 0; i < exits_.length(); ++i) { 410 for (int i = 0; i < exits_.length(); ++i) {
435 exits_[i].exit_block = exits_[i].exit_return->GetBlock(); 411 exits_[i].exit_block = exits_[i].exit_return->GetBlock();
436 } 412 }
437 exits_.Sort(LowestBlockIdFirst); 413 exits_.Sort(LowestBlockIdFirst);
438 } 414 }
439 415
440
441 Definition* InlineExitCollector::JoinReturns(BlockEntryInstr** exit_block, 416 Definition* InlineExitCollector::JoinReturns(BlockEntryInstr** exit_block,
442 Instruction** last_instruction, 417 Instruction** last_instruction,
443 intptr_t try_index) { 418 intptr_t try_index) {
444 // First sort the list of exits by block id (caching return instruction 419 // First sort the list of exits by block id (caching return instruction
445 // block entries as a side effect). 420 // block entries as a side effect).
446 SortExits(); 421 SortExits();
447 intptr_t num_exits = exits_.length(); 422 intptr_t num_exits = exits_.length();
448 if (num_exits == 1) { 423 if (num_exits == 1) {
449 ReturnAt(0)->UnuseAllInputs(); 424 ReturnAt(0)->UnuseAllInputs();
450 *exit_block = ExitBlockAt(0); 425 *exit_block = ExitBlockAt(0);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 // from their definition's use list. 511 // from their definition's use list.
537 for (intptr_t i = 0; i < num_exits; ++i) { 512 for (intptr_t i = 0; i < num_exits; ++i) {
538 ReturnAt(i)->UnuseAllInputs(); 513 ReturnAt(i)->UnuseAllInputs();
539 } 514 }
540 join->InheritDeoptTargetAfter(caller_graph_, call_, NULL); 515 join->InheritDeoptTargetAfter(caller_graph_, call_, NULL);
541 return NULL; 516 return NULL;
542 } 517 }
543 } 518 }
544 } 519 }
545 520
546
547 void InlineExitCollector::ReplaceCall(TargetEntryInstr* callee_entry) { 521 void InlineExitCollector::ReplaceCall(TargetEntryInstr* callee_entry) {
548 ASSERT(call_->previous() != NULL); 522 ASSERT(call_->previous() != NULL);
549 ASSERT(call_->next() != NULL); 523 ASSERT(call_->next() != NULL);
550 BlockEntryInstr* call_block = call_->GetBlock(); 524 BlockEntryInstr* call_block = call_->GetBlock();
551 525
552 // Insert the callee graph into the caller graph. 526 // Insert the callee graph into the caller graph.
553 BlockEntryInstr* callee_exit = NULL; 527 BlockEntryInstr* callee_exit = NULL;
554 Instruction* callee_last_instruction = NULL; 528 Instruction* callee_last_instruction = NULL;
555 529
556 if (exits_.length() == 0) { 530 if (exits_.length() == 0) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 callee_entry->UnuseAllInputs(); 626 callee_entry->UnuseAllInputs();
653 } 627 }
654 // Neither call nor the graph entry (if present) are in the 628 // Neither call nor the graph entry (if present) are in the
655 // graph at this point. Remove them from use lists. 629 // graph at this point. Remove them from use lists.
656 if (callee_entry->PredecessorCount() > 0) { 630 if (callee_entry->PredecessorCount() > 0) {
657 callee_entry->PredecessorAt(0)->AsGraphEntry()->UnuseAllInputs(); 631 callee_entry->PredecessorAt(0)->AsGraphEntry()->UnuseAllInputs();
658 } 632 }
659 call_->UnuseAllInputs(); 633 call_->UnuseAllInputs();
660 } 634 }
661 635
662
663 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { 636 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) {
664 ASSERT(is_open()); 637 ASSERT(is_open());
665 if (other_fragment.is_empty()) return; 638 if (other_fragment.is_empty()) return;
666 if (is_empty()) { 639 if (is_empty()) {
667 entry_ = other_fragment.entry(); 640 entry_ = other_fragment.entry();
668 } else { 641 } else {
669 exit()->LinkTo(other_fragment.entry()); 642 exit()->LinkTo(other_fragment.entry());
670 } 643 }
671 exit_ = other_fragment.exit(); 644 exit_ = other_fragment.exit();
672 } 645 }
673 646
674
675 Value* EffectGraphVisitor::Bind(Definition* definition) { 647 Value* EffectGraphVisitor::Bind(Definition* definition) {
676 ASSERT(is_open()); 648 ASSERT(is_open());
677 owner()->DeallocateTemps(definition->InputCount()); 649 owner()->DeallocateTemps(definition->InputCount());
678 owner()->add_args_pushed(-definition->ArgumentCount()); 650 owner()->add_args_pushed(-definition->ArgumentCount());
679 definition->set_temp_index(owner()->AllocateTemp()); 651 definition->set_temp_index(owner()->AllocateTemp());
680 if (is_empty()) { 652 if (is_empty()) {
681 entry_ = definition; 653 entry_ = definition;
682 } else { 654 } else {
683 exit()->LinkTo(definition); 655 exit()->LinkTo(definition);
684 } 656 }
685 exit_ = definition; 657 exit_ = definition;
686 return new (Z) Value(definition); 658 return new (Z) Value(definition);
687 } 659 }
688 660
689
690 void EffectGraphVisitor::Do(Definition* definition) { 661 void EffectGraphVisitor::Do(Definition* definition) {
691 ASSERT(is_open()); 662 ASSERT(is_open());
692 owner()->DeallocateTemps(definition->InputCount()); 663 owner()->DeallocateTemps(definition->InputCount());
693 owner()->add_args_pushed(-definition->ArgumentCount()); 664 owner()->add_args_pushed(-definition->ArgumentCount());
694 if (is_empty()) { 665 if (is_empty()) {
695 entry_ = definition; 666 entry_ = definition;
696 } else { 667 } else {
697 exit()->LinkTo(definition); 668 exit()->LinkTo(definition);
698 } 669 }
699 exit_ = definition; 670 exit_ = definition;
700 } 671 }
701 672
702
703 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { 673 void EffectGraphVisitor::AddInstruction(Instruction* instruction) {
704 ASSERT(is_open()); 674 ASSERT(is_open());
705 ASSERT(instruction->IsPushArgument() || !instruction->IsDefinition()); 675 ASSERT(instruction->IsPushArgument() || !instruction->IsDefinition());
706 ASSERT(!instruction->IsBlockEntry()); 676 ASSERT(!instruction->IsBlockEntry());
707 owner()->DeallocateTemps(instruction->InputCount()); 677 owner()->DeallocateTemps(instruction->InputCount());
708 owner()->add_args_pushed(-instruction->ArgumentCount()); 678 owner()->add_args_pushed(-instruction->ArgumentCount());
709 if (is_empty()) { 679 if (is_empty()) {
710 entry_ = exit_ = instruction; 680 entry_ = exit_ = instruction;
711 } else { 681 } else {
712 exit()->LinkTo(instruction); 682 exit()->LinkTo(instruction);
713 exit_ = instruction; 683 exit_ = instruction;
714 } 684 }
715 } 685 }
716 686
717
718 void EffectGraphVisitor::AddReturnExit(TokenPosition token_pos, Value* value) { 687 void EffectGraphVisitor::AddReturnExit(TokenPosition token_pos, Value* value) {
719 ASSERT(is_open()); 688 ASSERT(is_open());
720 ReturnInstr* return_instr = 689 ReturnInstr* return_instr =
721 new (Z) ReturnInstr(token_pos, value, owner()->GetNextDeoptId()); 690 new (Z) ReturnInstr(token_pos, value, owner()->GetNextDeoptId());
722 AddInstruction(return_instr); 691 AddInstruction(return_instr);
723 InlineExitCollector* exit_collector = owner()->exit_collector(); 692 InlineExitCollector* exit_collector = owner()->exit_collector();
724 if (exit_collector != NULL) { 693 if (exit_collector != NULL) {
725 exit_collector->AddExit(return_instr); 694 exit_collector->AddExit(return_instr);
726 } 695 }
727 CloseFragment(); 696 CloseFragment();
728 } 697 }
729 698
730
731 void EffectGraphVisitor::Goto(JoinEntryInstr* join) { 699 void EffectGraphVisitor::Goto(JoinEntryInstr* join) {
732 ASSERT(is_open()); 700 ASSERT(is_open());
733 if (is_empty()) { 701 if (is_empty()) {
734 entry_ = new (Z) GotoInstr(join, owner()->GetNextDeoptId()); 702 entry_ = new (Z) GotoInstr(join, owner()->GetNextDeoptId());
735 } else { 703 } else {
736 exit()->Goto(join); 704 exit()->Goto(join);
737 } 705 }
738 CloseFragment(); 706 CloseFragment();
739 } 707 }
740 708
741
742 // Appends a graph fragment to a block entry instruction. Returns the entry 709 // Appends a graph fragment to a block entry instruction. Returns the entry
743 // instruction if the fragment was empty or else the exit of the fragment if 710 // instruction if the fragment was empty or else the exit of the fragment if
744 // it was non-empty (so NULL if the fragment is closed). 711 // it was non-empty (so NULL if the fragment is closed).
745 // 712 //
746 // Note that the fragment is no longer a valid fragment after calling this 713 // Note that the fragment is no longer a valid fragment after calling this
747 // function -- the fragment is closed at its entry because the entry has a 714 // function -- the fragment is closed at its entry because the entry has a
748 // predecessor in the graph. 715 // predecessor in the graph.
749 static Instruction* AppendFragment(BlockEntryInstr* entry, 716 static Instruction* AppendFragment(BlockEntryInstr* entry,
750 const EffectGraphVisitor& fragment) { 717 const EffectGraphVisitor& fragment) {
751 if (fragment.is_empty()) return entry; 718 if (fragment.is_empty()) return entry;
752 entry->LinkTo(fragment.entry()); 719 entry->LinkTo(fragment.entry());
753 return fragment.exit(); 720 return fragment.exit();
754 } 721 }
755 722
756
757 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment, 723 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment,
758 const EffectGraphVisitor& true_fragment, 724 const EffectGraphVisitor& true_fragment,
759 const EffectGraphVisitor& false_fragment) { 725 const EffectGraphVisitor& false_fragment) {
760 // We have: a test graph fragment with zero, one, or two available exits; 726 // We have: a test graph fragment with zero, one, or two available exits;
761 // and a pair of effect graph fragments with zero or one available exits. 727 // and a pair of effect graph fragments with zero or one available exits.
762 // We want to append the branch and (if necessary) a join node to this 728 // We want to append the branch and (if necessary) a join node to this
763 // graph fragment. 729 // graph fragment.
764 ASSERT(is_open()); 730 ASSERT(is_open());
765 731
766 // 1. Connect the test to this graph. 732 // 1. Connect the test to this graph.
(...skipping 15 matching lines...) Expand all
782 } else { 748 } else {
783 JoinEntryInstr* join = 749 JoinEntryInstr* join =
784 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 750 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
785 owner()->GetNextDeoptId()); 751 owner()->GetNextDeoptId());
786 true_exit->Goto(join); 752 true_exit->Goto(join);
787 false_exit->Goto(join); 753 false_exit->Goto(join);
788 exit_ = join; 754 exit_ = join;
789 } 755 }
790 } 756 }
791 757
792
793 void EffectGraphVisitor::TieLoop( 758 void EffectGraphVisitor::TieLoop(
794 TokenPosition token_pos, 759 TokenPosition token_pos,
795 const TestGraphVisitor& test_fragment, 760 const TestGraphVisitor& test_fragment,
796 const EffectGraphVisitor& body_fragment, 761 const EffectGraphVisitor& body_fragment,
797 const EffectGraphVisitor& test_preamble_fragment) { 762 const EffectGraphVisitor& test_preamble_fragment) {
798 // We have: a test graph fragment with zero, one, or two available exits; 763 // We have: a test graph fragment with zero, one, or two available exits;
799 // and an effect graph fragment with zero or one available exits. We want 764 // and an effect graph fragment with zero or one available exits. We want
800 // to append the 'while loop' consisting of the test graph fragment as 765 // to append the 'while loop' consisting of the test graph fragment as
801 // condition and the effect graph fragment as body. 766 // condition and the effect graph fragment as body.
802 ASSERT(is_open()); 767 ASSERT(is_open());
(...skipping 23 matching lines...) Expand all
826 } 791 }
827 Goto(join); 792 Goto(join);
828 body_exit->Goto(join); 793 body_exit->Goto(join);
829 } 794 }
830 795
831 // 3. Set the exit to the graph to be the false successor of the test, a 796 // 3. Set the exit to the graph to be the false successor of the test, a
832 // fresh target node 797 // fresh target node
833 exit_ = test_fragment.CreateFalseSuccessor(); 798 exit_ = test_fragment.CreateFalseSuccessor();
834 } 799 }
835 800
836
837 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { 801 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) {
838 owner_->add_args_pushed(1); 802 owner_->add_args_pushed(1);
839 PushArgumentInstr* result = new (Z) PushArgumentInstr(value); 803 PushArgumentInstr* result = new (Z) PushArgumentInstr(value);
840 AddInstruction(result); 804 AddInstruction(result);
841 return result; 805 return result;
842 } 806 }
843 807
844
845 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local, 808 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local,
846 Value* value, 809 Value* value,
847 TokenPosition token_pos) { 810 TokenPosition token_pos) {
848 ASSERT(!local.is_captured()); 811 ASSERT(!local.is_captured());
849 ASSERT(!token_pos.IsClassifying()); 812 ASSERT(!token_pos.IsClassifying());
850 return new (Z) StoreLocalInstr(local, value, ST(token_pos)); 813 return new (Z) StoreLocalInstr(local, value, ST(token_pos));
851 } 814 }
852 815
853
854 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value, 816 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value,
855 TokenPosition token_pos) { 817 TokenPosition token_pos) {
856 return BuildStoreTemp(*owner()->parsed_function().expression_temp_var(), 818 return BuildStoreTemp(*owner()->parsed_function().expression_temp_var(),
857 value, token_pos); 819 value, token_pos);
858 } 820 }
859 821
860
861 Definition* EffectGraphVisitor::BuildLoadExprTemp(TokenPosition token_pos) { 822 Definition* EffectGraphVisitor::BuildLoadExprTemp(TokenPosition token_pos) {
862 ASSERT(!token_pos.IsClassifying()); 823 ASSERT(!token_pos.IsClassifying());
863 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var(), 824 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var(),
864 token_pos); 825 token_pos);
865 } 826 }
866 827
867
868 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, 828 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local,
869 Value* value, 829 Value* value,
870 TokenPosition token_pos) { 830 TokenPosition token_pos) {
871 if (local.is_captured()) { 831 if (local.is_captured()) {
872 LocalVariable* tmp_var = EnterTempLocalScope(value); 832 LocalVariable* tmp_var = EnterTempLocalScope(value);
873 intptr_t delta = owner()->context_level() - local.owner()->context_level(); 833 intptr_t delta = owner()->context_level() - local.owner()->context_level();
874 ASSERT(delta >= 0); 834 ASSERT(delta >= 0);
875 Value* context = Bind(BuildCurrentContext(token_pos)); 835 Value* context = Bind(BuildCurrentContext(token_pos));
876 while (delta-- > 0) { 836 while (delta-- > 0) {
877 context = Bind(new (Z) LoadFieldInstr(context, Context::parent_offset(), 837 context = Bind(new (Z) LoadFieldInstr(context, Context::parent_offset(),
878 Type::ZoneHandle(Z, Type::null()), 838 Type::ZoneHandle(Z, Type::null()),
879 token_pos)); 839 token_pos));
880 } 840 }
881 Value* tmp_val = Bind(new (Z) LoadLocalInstr(*tmp_var, token_pos)); 841 Value* tmp_val = Bind(new (Z) LoadLocalInstr(*tmp_var, token_pos));
882 StoreInstanceFieldInstr* store = new (Z) 842 StoreInstanceFieldInstr* store = new (Z)
883 StoreInstanceFieldInstr(Context::variable_offset(local.index()), 843 StoreInstanceFieldInstr(Context::variable_offset(local.index()),
884 context, tmp_val, kEmitStoreBarrier, token_pos); 844 context, tmp_val, kEmitStoreBarrier, token_pos);
885 Do(store); 845 Do(store);
886 return ExitTempLocalScope(value); 846 return ExitTempLocalScope(value);
887 } else { 847 } else {
888 return new (Z) StoreLocalInstr(local, value, token_pos); 848 return new (Z) StoreLocalInstr(local, value, token_pos);
889 } 849 }
890 } 850 }
891 851
892
893 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local, 852 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local,
894 TokenPosition token_pos) { 853 TokenPosition token_pos) {
895 if (local.IsConst()) { 854 if (local.IsConst()) {
896 return new (Z) ConstantInstr(*local.ConstValue(), token_pos); 855 return new (Z) ConstantInstr(*local.ConstValue(), token_pos);
897 } else if (local.is_captured()) { 856 } else if (local.is_captured()) {
898 intptr_t delta = owner()->context_level() - local.owner()->context_level(); 857 intptr_t delta = owner()->context_level() - local.owner()->context_level();
899 ASSERT(delta >= 0); 858 ASSERT(delta >= 0);
900 Value* context = Bind(BuildCurrentContext(token_pos)); 859 Value* context = Bind(BuildCurrentContext(token_pos));
901 while (delta-- > 0) { 860 while (delta-- > 0) {
902 context = Bind(new (Z) LoadFieldInstr(context, Context::parent_offset(), 861 context = Bind(new (Z) LoadFieldInstr(context, Context::parent_offset(),
903 Type::ZoneHandle(Z, Type::null()), 862 Type::ZoneHandle(Z, Type::null()),
904 token_pos)); 863 token_pos));
905 } 864 }
906 LoadFieldInstr* load = 865 LoadFieldInstr* load =
907 new (Z) LoadFieldInstr(context, Context::variable_offset(local.index()), 866 new (Z) LoadFieldInstr(context, Context::variable_offset(local.index()),
908 local.type(), token_pos); 867 local.type(), token_pos);
909 load->set_is_immutable(local.is_final()); 868 load->set_is_immutable(local.is_final());
910 return load; 869 return load;
911 } else { 870 } else {
912 return new (Z) LoadLocalInstr(local, token_pos); 871 return new (Z) LoadLocalInstr(local, token_pos);
913 } 872 }
914 } 873 }
915 874
916
917 // Stores current context into the 'variable' 875 // Stores current context into the 'variable'
918 void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable, 876 void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable,
919 TokenPosition token_pos) { 877 TokenPosition token_pos) {
920 ASSERT(token_pos.IsSynthetic() || token_pos.IsNoSource()); 878 ASSERT(token_pos.IsSynthetic() || token_pos.IsNoSource());
921 Value* context = Bind(BuildCurrentContext(token_pos)); 879 Value* context = Bind(BuildCurrentContext(token_pos));
922 Do(BuildStoreLocal(variable, context, token_pos)); 880 Do(BuildStoreLocal(variable, context, token_pos));
923 } 881 }
924 882
925
926 // Loads context saved in 'context_variable' into the current context. 883 // Loads context saved in 'context_variable' into the current context.
927 void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable, 884 void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable,
928 TokenPosition token_pos) { 885 TokenPosition token_pos) {
929 Value* load_saved_context = Bind(BuildLoadLocal(variable, token_pos)); 886 Value* load_saved_context = Bind(BuildLoadLocal(variable, token_pos));
930 Do(BuildStoreContext(load_saved_context, token_pos)); 887 Do(BuildStoreContext(load_saved_context, token_pos));
931 } 888 }
932 889
933
934 Definition* EffectGraphVisitor::BuildStoreContext(Value* value, 890 Definition* EffectGraphVisitor::BuildStoreContext(Value* value,
935 TokenPosition token_pos) { 891 TokenPosition token_pos) {
936 return new (Z) StoreLocalInstr( 892 return new (Z) StoreLocalInstr(
937 *owner()->parsed_function().current_context_var(), value, token_pos); 893 *owner()->parsed_function().current_context_var(), value, token_pos);
938 } 894 }
939 895
940
941 Definition* EffectGraphVisitor::BuildCurrentContext(TokenPosition token_pos) { 896 Definition* EffectGraphVisitor::BuildCurrentContext(TokenPosition token_pos) {
942 return new (Z) LoadLocalInstr( 897 return new (Z) LoadLocalInstr(
943 *owner()->parsed_function().current_context_var(), token_pos); 898 *owner()->parsed_function().current_context_var(), token_pos);
944 } 899 }
945 900
946
947 void TestGraphVisitor::ConnectBranchesTo( 901 void TestGraphVisitor::ConnectBranchesTo(
948 const GrowableArray<TargetEntryInstr**>& branches, 902 const GrowableArray<TargetEntryInstr**>& branches,
949 JoinEntryInstr* join) const { 903 JoinEntryInstr* join) const {
950 ASSERT(!branches.is_empty()); 904 ASSERT(!branches.is_empty());
951 for (intptr_t i = 0; i < branches.length(); i++) { 905 for (intptr_t i = 0; i < branches.length(); i++) {
952 TargetEntryInstr* target = new (Z) 906 TargetEntryInstr* target = new (Z)
953 TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 907 TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
954 owner()->GetNextDeoptId()); 908 owner()->GetNextDeoptId());
955 *(branches[i]) = target; 909 *(branches[i]) = target;
956 target->Goto(join); 910 target->Goto(join);
957 } 911 }
958 } 912 }
959 913
960
961 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const { 914 void TestGraphVisitor::IfTrueGoto(JoinEntryInstr* join) const {
962 ConnectBranchesTo(true_successor_addresses_, join); 915 ConnectBranchesTo(true_successor_addresses_, join);
963 } 916 }
964 917
965
966 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const { 918 void TestGraphVisitor::IfFalseGoto(JoinEntryInstr* join) const {
967 ConnectBranchesTo(false_successor_addresses_, join); 919 ConnectBranchesTo(false_successor_addresses_, join);
968 } 920 }
969 921
970
971 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor( 922 BlockEntryInstr* TestGraphVisitor::CreateSuccessorFor(
972 const GrowableArray<TargetEntryInstr**>& branches) const { 923 const GrowableArray<TargetEntryInstr**>& branches) const {
973 ASSERT(!branches.is_empty()); 924 ASSERT(!branches.is_empty());
974 925
975 if (branches.length() == 1) { 926 if (branches.length() == 1) {
976 TargetEntryInstr* target = new (Z) 927 TargetEntryInstr* target = new (Z)
977 TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 928 TargetEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
978 owner()->GetNextDeoptId()); 929 owner()->GetNextDeoptId());
979 *(branches[0]) = target; 930 *(branches[0]) = target;
980 return target; 931 return target;
981 } 932 }
982 933
983 JoinEntryInstr* join = 934 JoinEntryInstr* join =
984 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 935 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
985 owner()->GetNextDeoptId()); 936 owner()->GetNextDeoptId());
986 ConnectBranchesTo(branches, join); 937 ConnectBranchesTo(branches, join);
987 return join; 938 return join;
988 } 939 }
989 940
990
991 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const { 941 BlockEntryInstr* TestGraphVisitor::CreateTrueSuccessor() const {
992 return CreateSuccessorFor(true_successor_addresses_); 942 return CreateSuccessorFor(true_successor_addresses_);
993 } 943 }
994 944
995
996 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const { 945 BlockEntryInstr* TestGraphVisitor::CreateFalseSuccessor() const {
997 return CreateSuccessorFor(false_successor_addresses_); 946 return CreateSuccessorFor(false_successor_addresses_);
998 } 947 }
999 948
1000
1001 void TestGraphVisitor::ReturnValue(Value* value) { 949 void TestGraphVisitor::ReturnValue(Value* value) {
1002 Isolate* isolate = Isolate::Current(); 950 Isolate* isolate = Isolate::Current();
1003 if (isolate->type_checks() || isolate->asserts()) { 951 if (isolate->type_checks() || isolate->asserts()) {
1004 value = Bind(new (Z) AssertBooleanInstr(condition_token_pos(), value, 952 value = Bind(new (Z) AssertBooleanInstr(condition_token_pos(), value,
1005 owner()->GetNextDeoptId())); 953 owner()->GetNextDeoptId()));
1006 } 954 }
1007 Value* constant_true = Bind(new (Z) ConstantInstr(Bool::True())); 955 Value* constant_true = Bind(new (Z) ConstantInstr(Bool::True()));
1008 StrictCompareInstr* comp = new (Z) StrictCompareInstr( 956 StrictCompareInstr* comp = new (Z) StrictCompareInstr(
1009 condition_token_pos(), Token::kEQ_STRICT, value, constant_true, false, 957 condition_token_pos(), Token::kEQ_STRICT, value, constant_true, false,
1010 owner()->GetNextDeoptId()); // No number check. 958 owner()->GetNextDeoptId()); // No number check.
1011 BranchInstr* branch = new (Z) BranchInstr(comp, owner()->GetNextDeoptId()); 959 BranchInstr* branch = new (Z) BranchInstr(comp, owner()->GetNextDeoptId());
1012 AddInstruction(branch); 960 AddInstruction(branch);
1013 CloseFragment(); 961 CloseFragment();
1014 962
1015 true_successor_addresses_.Add(branch->true_successor_address()); 963 true_successor_addresses_.Add(branch->true_successor_address());
1016 false_successor_addresses_.Add(branch->false_successor_address()); 964 false_successor_addresses_.Add(branch->false_successor_address());
1017 } 965 }
1018 966
1019
1020 void TestGraphVisitor::MergeBranchWithStrictCompare(StrictCompareInstr* comp) { 967 void TestGraphVisitor::MergeBranchWithStrictCompare(StrictCompareInstr* comp) {
1021 BranchInstr* branch = new (Z) BranchInstr(comp, owner()->GetNextDeoptId()); 968 BranchInstr* branch = new (Z) BranchInstr(comp, owner()->GetNextDeoptId());
1022 AddInstruction(branch); 969 AddInstruction(branch);
1023 CloseFragment(); 970 CloseFragment();
1024 true_successor_addresses_.Add(branch->true_successor_address()); 971 true_successor_addresses_.Add(branch->true_successor_address());
1025 false_successor_addresses_.Add(branch->false_successor_address()); 972 false_successor_addresses_.Add(branch->false_successor_address());
1026 } 973 }
1027 974
1028
1029 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) { 975 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) {
1030 ASSERT(!Isolate::Current()->type_checks()); 976 ASSERT(!Isolate::Current()->type_checks());
1031 Value* constant_true = Bind(new (Z) ConstantInstr(Bool::True())); 977 Value* constant_true = Bind(new (Z) ConstantInstr(Bool::True()));
1032 StrictCompareInstr* comp = new (Z) StrictCompareInstr( 978 StrictCompareInstr* comp = new (Z) StrictCompareInstr(
1033 condition_token_pos(), Token::kNE_STRICT, neg->value(), constant_true, 979 condition_token_pos(), Token::kNE_STRICT, neg->value(), constant_true,
1034 false, owner()->GetNextDeoptId()); // No number check. 980 false, owner()->GetNextDeoptId()); // No number check.
1035 BranchInstr* branch = new (Z) BranchInstr(comp, owner()->GetNextDeoptId()); 981 BranchInstr* branch = new (Z) BranchInstr(comp, owner()->GetNextDeoptId());
1036 AddInstruction(branch); 982 AddInstruction(branch);
1037 CloseFragment(); 983 CloseFragment();
1038 true_successor_addresses_.Add(branch->true_successor_address()); 984 true_successor_addresses_.Add(branch->true_successor_address());
1039 false_successor_addresses_.Add(branch->false_successor_address()); 985 false_successor_addresses_.Add(branch->false_successor_address());
1040 } 986 }
1041 987
1042
1043 void TestGraphVisitor::ReturnDefinition(Definition* definition) { 988 void TestGraphVisitor::ReturnDefinition(Definition* definition) {
1044 StrictCompareInstr* comp = definition->AsStrictCompare(); 989 StrictCompareInstr* comp = definition->AsStrictCompare();
1045 if (comp != NULL) { 990 if (comp != NULL) {
1046 MergeBranchWithStrictCompare(comp); 991 MergeBranchWithStrictCompare(comp);
1047 return; 992 return;
1048 } 993 }
1049 if (!Isolate::Current()->type_checks()) { 994 if (!Isolate::Current()->type_checks()) {
1050 BooleanNegateInstr* neg = definition->AsBooleanNegate(); 995 BooleanNegateInstr* neg = definition->AsBooleanNegate();
1051 if (neg != NULL) { 996 if (neg != NULL) {
1052 MergeBranchWithNegate(neg); 997 MergeBranchWithNegate(neg);
1053 return; 998 return;
1054 } 999 }
1055 } 1000 }
1056 ReturnValue(Bind(definition)); 1001 ReturnValue(Bind(definition));
1057 } 1002 }
1058 1003
1059
1060 // Special handling for AND/OR. 1004 // Special handling for AND/OR.
1061 void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 1005 void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
1062 // Operators "&&" and "||" cannot be overloaded therefore do not call 1006 // Operators "&&" and "||" cannot be overloaded therefore do not call
1063 // operator. 1007 // operator.
1064 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 1008 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
1065 TestGraphVisitor for_left(owner(), node->left()->token_pos()); 1009 TestGraphVisitor for_left(owner(), node->left()->token_pos());
1066 node->left()->Visit(&for_left); 1010 node->left()->Visit(&for_left);
1067 1011
1068 TestGraphVisitor for_right(owner(), node->right()->token_pos()); 1012 TestGraphVisitor for_right(owner(), node->right()->token_pos());
1069 node->right()->Visit(&for_right); 1013 node->right()->Visit(&for_right);
(...skipping 11 matching lines...) Expand all
1081 false_successor_addresses_.AddArray(for_right.false_successor_addresses_); 1025 false_successor_addresses_.AddArray(for_right.false_successor_addresses_);
1082 true_successor_addresses_.AddArray(for_left.true_successor_addresses_); 1026 true_successor_addresses_.AddArray(for_left.true_successor_addresses_);
1083 true_successor_addresses_.AddArray(for_right.true_successor_addresses_); 1027 true_successor_addresses_.AddArray(for_right.true_successor_addresses_);
1084 } 1028 }
1085 CloseFragment(); 1029 CloseFragment();
1086 return; 1030 return;
1087 } 1031 }
1088 ValueGraphVisitor::VisitBinaryOpNode(node); 1032 ValueGraphVisitor::VisitBinaryOpNode(node);
1089 } 1033 }
1090 1034
1091
1092 void EffectGraphVisitor::Bailout(const char* reason) const { 1035 void EffectGraphVisitor::Bailout(const char* reason) const {
1093 owner()->Bailout(reason); 1036 owner()->Bailout(reason);
1094 } 1037 }
1095 1038
1096
1097 void EffectGraphVisitor::InlineBailout(const char* reason) const { 1039 void EffectGraphVisitor::InlineBailout(const char* reason) const {
1098 owner()->function().set_is_inlinable(false); 1040 owner()->function().set_is_inlinable(false);
1099 if (owner()->IsInlining()) owner()->Bailout(reason); 1041 if (owner()->IsInlining()) owner()->Bailout(reason);
1100 } 1042 }
1101 1043
1102
1103 // <Statement> ::= Return { value: <Expression> 1044 // <Statement> ::= Return { value: <Expression>
1104 // inlined_finally_list: <InlinedFinally>* } 1045 // inlined_finally_list: <InlinedFinally>* }
1105 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { 1046 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) {
1106 ValueGraphVisitor for_value(owner()); 1047 ValueGraphVisitor for_value(owner());
1107 node->value()->Visit(&for_value); 1048 node->value()->Visit(&for_value);
1108 Append(for_value); 1049 Append(for_value);
1109 Value* return_value = for_value.value(); 1050 Value* return_value = for_value.value();
1110 1051
1111 // Call to stub that checks whether the debugger is in single 1052 // Call to stub that checks whether the debugger is in single
1112 // step mode. This call must happen before the contexts are 1053 // step mode. This call must happen before the contexts are
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 function.IsAsyncGenClosure()) && 1167 function.IsAsyncGenClosure()) &&
1227 (node->return_type() == ReturnNode::kContinuationTarget)) { 1168 (node->return_type() == ReturnNode::kContinuationTarget)) {
1228 JoinEntryInstr* const join = 1169 JoinEntryInstr* const join =
1229 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(), 1170 new (Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index(),
1230 owner()->GetNextDeoptId()); 1171 owner()->GetNextDeoptId());
1231 owner()->await_joins()->Add(join); 1172 owner()->await_joins()->Add(join);
1232 exit_ = join; 1173 exit_ = join;
1233 } 1174 }
1234 } 1175 }
1235 1176
1236
1237 // <Expression> ::= Literal { literal: Instance } 1177 // <Expression> ::= Literal { literal: Instance }
1238 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) { 1178 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) {
1239 ReturnDefinition(new (Z) ConstantInstr(node->literal(), node->token_pos())); 1179 ReturnDefinition(new (Z) ConstantInstr(node->literal(), node->token_pos()));
1240 } 1180 }
1241 1181
1242
1243 // Type nodes are used when a type is referenced as a literal. Type nodes 1182 // Type nodes are used when a type is referenced as a literal. Type nodes
1244 // can also be used for the right-hand side of instanceof comparisons, 1183 // can also be used for the right-hand side of instanceof comparisons,
1245 // but they are handled specially in that context, not here. 1184 // but they are handled specially in that context, not here.
1246 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { 1185 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) {
1247 return; 1186 return;
1248 } 1187 }
1249 1188
1250
1251 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { 1189 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) {
1252 const AbstractType& type = node->type(); 1190 const AbstractType& type = node->type();
1253 // Type may be malbounded, but not malformed. 1191 // Type may be malbounded, but not malformed.
1254 ASSERT(type.IsFinalized() && !type.IsMalformed()); 1192 ASSERT(type.IsFinalized() && !type.IsMalformed());
1255 if (type.IsInstantiated()) { 1193 if (type.IsInstantiated()) {
1256 ReturnDefinition(new (Z) ConstantInstr(type)); 1194 ReturnDefinition(new (Z) ConstantInstr(type));
1257 return; 1195 return;
1258 } 1196 }
1259 const TokenPosition token_pos = node->token_pos(); 1197 const TokenPosition token_pos = node->token_pos();
1260 Value* instantiator_type_arguments = NULL; 1198 Value* instantiator_type_arguments = NULL;
1261 if (type.IsInstantiated(kCurrentClass)) { 1199 if (type.IsInstantiated(kCurrentClass)) {
1262 instantiator_type_arguments = BuildNullValue(token_pos); 1200 instantiator_type_arguments = BuildNullValue(token_pos);
1263 } else { 1201 } else {
1264 instantiator_type_arguments = BuildInstantiatorTypeArguments(token_pos); 1202 instantiator_type_arguments = BuildInstantiatorTypeArguments(token_pos);
1265 } 1203 }
1266 Value* function_type_arguments = NULL; 1204 Value* function_type_arguments = NULL;
1267 if (type.IsInstantiated(kFunctions)) { 1205 if (type.IsInstantiated(kFunctions)) {
1268 function_type_arguments = BuildNullValue(token_pos); 1206 function_type_arguments = BuildNullValue(token_pos);
1269 } else { 1207 } else {
1270 function_type_arguments = BuildFunctionTypeArguments(token_pos); 1208 function_type_arguments = BuildFunctionTypeArguments(token_pos);
1271 } 1209 }
1272 ReturnDefinition(new (Z) InstantiateTypeInstr( 1210 ReturnDefinition(new (Z) InstantiateTypeInstr(
1273 token_pos, type, instantiator_type_arguments, function_type_arguments, 1211 token_pos, type, instantiator_type_arguments, function_type_arguments,
1274 owner()->GetNextDeoptId())); 1212 owner()->GetNextDeoptId()));
1275 } 1213 }
1276 1214
1277
1278 // Returns true if the type check can be skipped, for example, if the 1215 // Returns true if the type check can be skipped, for example, if the
1279 // destination type is dynamic or if the compile type of the value is a subtype 1216 // destination type is dynamic or if the compile type of the value is a subtype
1280 // of the destination type. 1217 // of the destination type.
1281 bool EffectGraphVisitor::CanSkipTypeCheck(TokenPosition token_pos, 1218 bool EffectGraphVisitor::CanSkipTypeCheck(TokenPosition token_pos,
1282 Value* value, 1219 Value* value,
1283 const AbstractType& dst_type, 1220 const AbstractType& dst_type,
1284 const String& dst_name) { 1221 const String& dst_name) {
1285 ASSERT(!dst_type.IsNull()); 1222 ASSERT(!dst_type.IsNull());
1286 ASSERT(dst_type.IsFinalized()); 1223 ASSERT(dst_type.IsFinalized());
1287 1224
(...skipping 22 matching lines...) Expand all
1310 } 1247 }
1311 1248
1312 const bool eliminated = value->Type()->IsAssignableTo(dst_type); 1249 const bool eliminated = value->Type()->IsAssignableTo(dst_type);
1313 if (FLAG_trace_type_check_elimination) { 1250 if (FLAG_trace_type_check_elimination) {
1314 FlowGraphPrinter::PrintTypeCheck(owner()->parsed_function(), token_pos, 1251 FlowGraphPrinter::PrintTypeCheck(owner()->parsed_function(), token_pos,
1315 value, dst_type, dst_name, eliminated); 1252 value, dst_type, dst_name, eliminated);
1316 } 1253 }
1317 return eliminated; 1254 return eliminated;
1318 } 1255 }
1319 1256
1320
1321 // <Expression> :: Assignable { expr: <Expression> 1257 // <Expression> :: Assignable { expr: <Expression>
1322 // type: AbstractType 1258 // type: AbstractType
1323 // dst_name: String } 1259 // dst_name: String }
1324 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { 1260 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) {
1325 ValueGraphVisitor for_value(owner()); 1261 ValueGraphVisitor for_value(owner());
1326 node->expr()->Visit(&for_value); 1262 node->expr()->Visit(&for_value);
1327 Append(for_value); 1263 Append(for_value);
1328 if (CanSkipTypeCheck(node->expr()->token_pos(), for_value.value(), 1264 if (CanSkipTypeCheck(node->expr()->token_pos(), for_value.value(),
1329 node->type(), node->dst_name())) { 1265 node->type(), node->dst_name())) {
1330 ReturnValue(for_value.value()); 1266 ReturnValue(for_value.value());
1331 } else { 1267 } else {
1332 ReturnDefinition(BuildAssertAssignable(node->expr()->token_pos(), 1268 ReturnDefinition(BuildAssertAssignable(node->expr()->token_pos(),
1333 for_value.value(), node->type(), 1269 for_value.value(), node->type(),
1334 node->dst_name())); 1270 node->dst_name()));
1335 } 1271 }
1336 } 1272 }
1337 1273
1338
1339 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { 1274 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) {
1340 ValueGraphVisitor for_value(owner()); 1275 ValueGraphVisitor for_value(owner());
1341 node->expr()->Visit(&for_value); 1276 node->expr()->Visit(&for_value);
1342 Append(for_value); 1277 Append(for_value);
1343 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), for_value.value(), 1278 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), for_value.value(),
1344 node->type(), node->dst_name())); 1279 node->type(), node->dst_name()));
1345 } 1280 }
1346 1281
1347
1348 // <Expression> :: BinaryOp { kind: Token::Kind 1282 // <Expression> :: BinaryOp { kind: Token::Kind
1349 // left: <Expression> 1283 // left: <Expression>
1350 // right: <Expression> } 1284 // right: <Expression> }
1351 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 1285 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
1352 // Operators "&&" and "||" cannot be overloaded therefore do not call 1286 // Operators "&&" and "||" cannot be overloaded therefore do not call
1353 // operator. 1287 // operator.
1354 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 1288 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
1355 // See ValueGraphVisitor::VisitBinaryOpNode. 1289 // See ValueGraphVisitor::VisitBinaryOpNode.
1356 TestGraphVisitor for_left(owner(), node->left()->token_pos()); 1290 TestGraphVisitor for_left(owner(), node->left()->token_pos());
1357 node->left()->Visit(&for_left); 1291 node->left()->Visit(&for_left);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1397 const String& name = Symbols::Token(node->kind()); 1331 const String& name = Symbols::Token(node->kind());
1398 const intptr_t kTypeArgsLen = 0; 1332 const intptr_t kTypeArgsLen = 0;
1399 const intptr_t kNumArgsChecked = 2; 1333 const intptr_t kNumArgsChecked = 2;
1400 InstanceCallInstr* call = new (Z) 1334 InstanceCallInstr* call = new (Z)
1401 InstanceCallInstr(node->token_pos(), name, node->kind(), arguments, 1335 InstanceCallInstr(node->token_pos(), name, node->kind(), arguments,
1402 kTypeArgsLen, Object::null_array(), kNumArgsChecked, 1336 kTypeArgsLen, Object::null_array(), kNumArgsChecked,
1403 owner()->ic_data_array(), owner()->GetNextDeoptId()); 1337 owner()->ic_data_array(), owner()->GetNextDeoptId());
1404 ReturnDefinition(call); 1338 ReturnDefinition(call);
1405 } 1339 }
1406 1340
1407
1408 // Special handling for AND/OR. 1341 // Special handling for AND/OR.
1409 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) { 1342 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
1410 // Operators "&&" and "||" cannot be overloaded therefore do not call 1343 // Operators "&&" and "||" cannot be overloaded therefore do not call
1411 // operator. 1344 // operator.
1412 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) { 1345 if ((node->kind() == Token::kAND) || (node->kind() == Token::kOR)) {
1413 // Implement short-circuit logic: do not evaluate right if evaluation 1346 // Implement short-circuit logic: do not evaluate right if evaluation
1414 // of left is sufficient. 1347 // of left is sufficient.
1415 // AND: left ? right === true : false; 1348 // AND: left ? right === true : false;
1416 // OR: left ? true : right === true; 1349 // OR: left ? true : right === true;
1417 1350
(...skipping 27 matching lines...) Expand all
1445 for_true.Do(BuildStoreExprTemp(constant_true, node->token_pos())); 1378 for_true.Do(BuildStoreExprTemp(constant_true, node->token_pos()));
1446 Join(for_test, for_true, for_right); 1379 Join(for_test, for_true, for_right);
1447 } 1380 }
1448 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); 1381 ReturnDefinition(BuildLoadExprTemp(node->token_pos()));
1449 return; 1382 return;
1450 } 1383 }
1451 1384
1452 EffectGraphVisitor::VisitBinaryOpNode(node); 1385 EffectGraphVisitor::VisitBinaryOpNode(node);
1453 } 1386 }
1454 1387
1455
1456 PushArgumentInstr* EffectGraphVisitor::PushInstantiatorTypeArguments( 1388 PushArgumentInstr* EffectGraphVisitor::PushInstantiatorTypeArguments(
1457 const AbstractType& type, 1389 const AbstractType& type,
1458 TokenPosition token_pos) { 1390 TokenPosition token_pos) {
1459 if (type.IsInstantiated(kCurrentClass)) { 1391 if (type.IsInstantiated(kCurrentClass)) {
1460 return PushArgument(BuildNullValue(token_pos)); 1392 return PushArgument(BuildNullValue(token_pos));
1461 } else { 1393 } else {
1462 Value* instantiator_type_args = BuildInstantiatorTypeArguments(token_pos); 1394 Value* instantiator_type_args = BuildInstantiatorTypeArguments(token_pos);
1463 return PushArgument(instantiator_type_args); 1395 return PushArgument(instantiator_type_args);
1464 } 1396 }
1465 } 1397 }
1466 1398
1467
1468 PushArgumentInstr* EffectGraphVisitor::PushFunctionTypeArguments( 1399 PushArgumentInstr* EffectGraphVisitor::PushFunctionTypeArguments(
1469 const AbstractType& type, 1400 const AbstractType& type,
1470 TokenPosition token_pos) { 1401 TokenPosition token_pos) {
1471 if (type.IsInstantiated(kFunctions)) { 1402 if (type.IsInstantiated(kFunctions)) {
1472 return PushArgument(BuildNullValue(token_pos)); 1403 return PushArgument(BuildNullValue(token_pos));
1473 } else { 1404 } else {
1474 Value* function_type_args = BuildFunctionTypeArguments(token_pos); 1405 Value* function_type_args = BuildFunctionTypeArguments(token_pos);
1475 return PushArgument(function_type_args); 1406 return PushArgument(function_type_args);
1476 } 1407 }
1477 } 1408 }
1478 1409
1479
1480 Value* EffectGraphVisitor::BuildNullValue(TokenPosition token_pos) { 1410 Value* EffectGraphVisitor::BuildNullValue(TokenPosition token_pos) {
1481 return Bind( 1411 return Bind(
1482 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()), token_pos)); 1412 new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()), token_pos));
1483 } 1413 }
1484 1414
1485
1486 Value* EffectGraphVisitor::BuildEmptyTypeArguments(TokenPosition token_pos) { 1415 Value* EffectGraphVisitor::BuildEmptyTypeArguments(TokenPosition token_pos) {
1487 return Bind(new (Z) ConstantInstr( 1416 return Bind(new (Z) ConstantInstr(
1488 TypeArguments::ZoneHandle(Z, Object::empty_type_arguments().raw()), 1417 TypeArguments::ZoneHandle(Z, Object::empty_type_arguments().raw()),
1489 token_pos)); 1418 token_pos));
1490 } 1419 }
1491 1420
1492
1493 // Used for testing incoming arguments. 1421 // Used for testing incoming arguments.
1494 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( 1422 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable(
1495 TokenPosition token_pos, 1423 TokenPosition token_pos,
1496 Value* value, 1424 Value* value,
1497 const AbstractType& dst_type, 1425 const AbstractType& dst_type,
1498 const String& dst_name) { 1426 const String& dst_name) {
1499 // Build the type check computation. 1427 // Build the type check computation.
1500 Value* instantiator_type_arguments = NULL; 1428 Value* instantiator_type_arguments = NULL;
1501 Value* function_type_arguments = NULL; 1429 Value* function_type_arguments = NULL;
1502 if (dst_type.IsInstantiated(kCurrentClass)) { 1430 if (dst_type.IsInstantiated(kCurrentClass)) {
1503 instantiator_type_arguments = BuildNullValue(token_pos); 1431 instantiator_type_arguments = BuildNullValue(token_pos);
1504 } else { 1432 } else {
1505 instantiator_type_arguments = BuildInstantiatorTypeArguments(token_pos); 1433 instantiator_type_arguments = BuildInstantiatorTypeArguments(token_pos);
1506 } 1434 }
1507 if (dst_type.IsInstantiated(kFunctions)) { 1435 if (dst_type.IsInstantiated(kFunctions)) {
1508 function_type_arguments = BuildNullValue(token_pos); 1436 function_type_arguments = BuildNullValue(token_pos);
1509 } else { 1437 } else {
1510 function_type_arguments = BuildFunctionTypeArguments(token_pos); 1438 function_type_arguments = BuildFunctionTypeArguments(token_pos);
1511 } 1439 }
1512 1440
1513 const intptr_t deopt_id = owner()->GetNextDeoptId(); 1441 const intptr_t deopt_id = owner()->GetNextDeoptId();
1514 return new (Z) AssertAssignableInstr( 1442 return new (Z) AssertAssignableInstr(
1515 token_pos, value, instantiator_type_arguments, function_type_arguments, 1443 token_pos, value, instantiator_type_arguments, function_type_arguments,
1516 dst_type, dst_name, deopt_id); 1444 dst_type, dst_name, deopt_id);
1517 } 1445 }
1518 1446
1519
1520 // Used for type casts and to test assignments. 1447 // Used for type casts and to test assignments.
1521 Value* EffectGraphVisitor::BuildAssignableValue(TokenPosition token_pos, 1448 Value* EffectGraphVisitor::BuildAssignableValue(TokenPosition token_pos,
1522 Value* value, 1449 Value* value,
1523 const AbstractType& dst_type, 1450 const AbstractType& dst_type,
1524 const String& dst_name) { 1451 const String& dst_name) {
1525 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) { 1452 if (CanSkipTypeCheck(token_pos, value, dst_type, dst_name)) {
1526 return value; 1453 return value;
1527 } 1454 }
1528 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name)); 1455 return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name));
1529 } 1456 }
1530 1457
1531
1532 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { 1458 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) {
1533 ASSERT(Token::IsTypeTestOperator(node->kind())); 1459 ASSERT(Token::IsTypeTestOperator(node->kind()));
1534 const AbstractType& type = node->right()->AsTypeNode()->type(); 1460 const AbstractType& type = node->right()->AsTypeNode()->type();
1535 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); 1461 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
1536 const bool negate_result = (node->kind() == Token::kISNOT); 1462 const bool negate_result = (node->kind() == Token::kISNOT);
1537 // All objects are instances of type T if Object type is a subtype of type T. 1463 // All objects are instances of type T if Object type is a subtype of type T.
1538 const Type& object_type = Type::Handle(Z, Type::ObjectType()); 1464 const Type& object_type = Type::Handle(Z, Type::ObjectType());
1539 if (type.IsInstantiated() && 1465 if (type.IsInstantiated() &&
1540 object_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) { 1466 object_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) {
1541 // Must evaluate left side. 1467 // Must evaluate left side.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 node->token_pos(), Library::PrivateCoreLibName(Symbols::_instanceOf()), 1516 node->token_pos(), Library::PrivateCoreLibName(Symbols::_instanceOf()),
1591 node->kind(), arguments, kTypeArgsLen, 1517 node->kind(), arguments, kTypeArgsLen,
1592 Object::null_array(), // No argument names. 1518 Object::null_array(), // No argument names.
1593 kNumArgsChecked, owner()->ic_data_array(), owner()->GetNextDeoptId()); 1519 kNumArgsChecked, owner()->ic_data_array(), owner()->GetNextDeoptId());
1594 if (negate_result) { 1520 if (negate_result) {
1595 result = new (Z) BooleanNegateInstr(Bind(result)); 1521 result = new (Z) BooleanNegateInstr(Bind(result));
1596 } 1522 }
1597 ReturnDefinition(result); 1523 ReturnDefinition(result);
1598 } 1524 }
1599 1525
1600
1601 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) { 1526 void EffectGraphVisitor::BuildTypeCast(ComparisonNode* node) {
1602 ASSERT(Token::IsTypeCastOperator(node->kind())); 1527 ASSERT(Token::IsTypeCastOperator(node->kind()));
1603 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); 1528 ASSERT(!node->right()->AsTypeNode()->type().IsNull());
1604 const AbstractType& type = node->right()->AsTypeNode()->type(); 1529 const AbstractType& type = node->right()->AsTypeNode()->type();
1605 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded()); 1530 ASSERT(type.IsFinalized() && !type.IsMalformed() && !type.IsMalbounded());
1606 ValueGraphVisitor for_value(owner()); 1531 ValueGraphVisitor for_value(owner());
1607 node->left()->Visit(&for_value); 1532 node->left()->Visit(&for_value);
1608 Append(for_value); 1533 Append(for_value);
1609 if (CanSkipTypeCheck(node->token_pos(), for_value.value(), type, 1534 if (CanSkipTypeCheck(node->token_pos(), for_value.value(), type,
1610 Symbols::InTypeCast())) { 1535 Symbols::InTypeCast())) {
(...skipping 15 matching lines...) Expand all
1626 const int kTypeArgsLen = 0; 1551 const int kTypeArgsLen = 0;
1627 const intptr_t kNumArgsChecked = 1; 1552 const intptr_t kNumArgsChecked = 1;
1628 InstanceCallInstr* call = new (Z) InstanceCallInstr( 1553 InstanceCallInstr* call = new (Z) InstanceCallInstr(
1629 node->token_pos(), Library::PrivateCoreLibName(Symbols::_as()), 1554 node->token_pos(), Library::PrivateCoreLibName(Symbols::_as()),
1630 node->kind(), arguments, kTypeArgsLen, 1555 node->kind(), arguments, kTypeArgsLen,
1631 Object::null_array(), // No argument names. 1556 Object::null_array(), // No argument names.
1632 kNumArgsChecked, owner()->ic_data_array(), owner()->GetNextDeoptId()); 1557 kNumArgsChecked, owner()->ic_data_array(), owner()->GetNextDeoptId());
1633 ReturnDefinition(call); 1558 ReturnDefinition(call);
1634 } 1559 }
1635 1560
1636
1637 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare( 1561 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare(
1638 AstNode* left, 1562 AstNode* left,
1639 AstNode* right, 1563 AstNode* right,
1640 Token::Kind kind, 1564 Token::Kind kind,
1641 TokenPosition token_pos) { 1565 TokenPosition token_pos) {
1642 ValueGraphVisitor for_left_value(owner()); 1566 ValueGraphVisitor for_left_value(owner());
1643 left->Visit(&for_left_value); 1567 left->Visit(&for_left_value);
1644 Append(for_left_value); 1568 Append(for_left_value);
1645 ValueGraphVisitor for_right_value(owner()); 1569 ValueGraphVisitor for_right_value(owner());
1646 right->Visit(&for_right_value); 1570 right->Visit(&for_right_value);
1647 Append(for_right_value); 1571 Append(for_right_value);
1648 StrictCompareInstr* comp = new (Z) StrictCompareInstr( 1572 StrictCompareInstr* comp = new (Z) StrictCompareInstr(
1649 token_pos, kind, for_left_value.value(), for_right_value.value(), true, 1573 token_pos, kind, for_left_value.value(), for_right_value.value(), true,
1650 owner()->GetNextDeoptId()); // Number check. 1574 owner()->GetNextDeoptId()); // Number check.
1651 return comp; 1575 return comp;
1652 } 1576 }
1653 1577
1654
1655 // <Expression> :: Comparison { kind: Token::Kind 1578 // <Expression> :: Comparison { kind: Token::Kind
1656 // left: <Expression> 1579 // left: <Expression>
1657 // right: <Expression> } 1580 // right: <Expression> }
1658 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { 1581 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
1659 if (Token::IsTypeTestOperator(node->kind())) { 1582 if (Token::IsTypeTestOperator(node->kind())) {
1660 BuildTypeTest(node); 1583 BuildTypeTest(node);
1661 return; 1584 return;
1662 } 1585 }
1663 if (Token::IsTypeCastOperator(node->kind())) { 1586 if (Token::IsTypeCastOperator(node->kind())) {
1664 BuildTypeCast(node); 1587 BuildTypeCast(node);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1739 1662
1740 ASSERT(Token::IsRelationalOperator(node->kind())); 1663 ASSERT(Token::IsRelationalOperator(node->kind()));
1741 const intptr_t kTypeArgsLen = 0; 1664 const intptr_t kTypeArgsLen = 0;
1742 InstanceCallInstr* comp = new (Z) InstanceCallInstr( 1665 InstanceCallInstr* comp = new (Z) InstanceCallInstr(
1743 node->token_pos(), Symbols::Token(node->kind()), node->kind(), arguments, 1666 node->token_pos(), Symbols::Token(node->kind()), node->kind(), arguments,
1744 kTypeArgsLen, Object::null_array(), 2, owner()->ic_data_array(), 1667 kTypeArgsLen, Object::null_array(), 2, owner()->ic_data_array(),
1745 owner()->GetNextDeoptId()); 1668 owner()->GetNextDeoptId());
1746 ReturnDefinition(comp); 1669 ReturnDefinition(comp);
1747 } 1670 }
1748 1671
1749
1750 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { 1672 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
1751 // "!" cannot be overloaded, therefore do not call operator. 1673 // "!" cannot be overloaded, therefore do not call operator.
1752 if (node->kind() == Token::kNOT) { 1674 if (node->kind() == Token::kNOT) {
1753 ValueGraphVisitor for_value(owner()); 1675 ValueGraphVisitor for_value(owner());
1754 node->operand()->Visit(&for_value); 1676 node->operand()->Visit(&for_value);
1755 Append(for_value); 1677 Append(for_value);
1756 Value* value = for_value.value(); 1678 Value* value = for_value.value();
1757 Isolate* isolate = Isolate::Current(); 1679 Isolate* isolate = Isolate::Current();
1758 if (isolate->type_checks() || isolate->asserts()) { 1680 if (isolate->type_checks() || isolate->asserts()) {
1759 value = Bind(new (Z) AssertBooleanInstr( 1681 value = Bind(new (Z) AssertBooleanInstr(
(...skipping 12 matching lines...) Expand all
1772 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1); 1694 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1);
1773 arguments->Add(push_value); 1695 arguments->Add(push_value);
1774 const intptr_t kTypeArgsLen = 0; 1696 const intptr_t kTypeArgsLen = 0;
1775 InstanceCallInstr* call = new (Z) InstanceCallInstr( 1697 InstanceCallInstr* call = new (Z) InstanceCallInstr(
1776 node->token_pos(), Symbols::Token(node->kind()), node->kind(), arguments, 1698 node->token_pos(), Symbols::Token(node->kind()), node->kind(), arguments,
1777 kTypeArgsLen, Object::null_array(), 1, owner()->ic_data_array(), 1699 kTypeArgsLen, Object::null_array(), 1, owner()->ic_data_array(),
1778 owner()->GetNextDeoptId()); 1700 owner()->GetNextDeoptId());
1779 ReturnDefinition(call); 1701 ReturnDefinition(call);
1780 } 1702 }
1781 1703
1782
1783 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 1704 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
1784 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); 1705 TestGraphVisitor for_test(owner(), node->condition()->token_pos());
1785 node->condition()->Visit(&for_test); 1706 node->condition()->Visit(&for_test);
1786 1707
1787 // Translate the subexpressions for their effects. 1708 // Translate the subexpressions for their effects.
1788 EffectGraphVisitor for_true(owner()); 1709 EffectGraphVisitor for_true(owner());
1789 node->true_expr()->Visit(&for_true); 1710 node->true_expr()->Visit(&for_true);
1790 EffectGraphVisitor for_false(owner()); 1711 EffectGraphVisitor for_false(owner());
1791 node->false_expr()->Visit(&for_false); 1712 node->false_expr()->Visit(&for_false);
1792 1713
1793 Join(for_test, for_true, for_false); 1714 Join(for_test, for_true, for_false);
1794 } 1715 }
1795 1716
1796
1797 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 1717 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
1798 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); 1718 TestGraphVisitor for_test(owner(), node->condition()->token_pos());
1799 node->condition()->Visit(&for_test); 1719 node->condition()->Visit(&for_test);
1800 1720
1801 ValueGraphVisitor for_true(owner()); 1721 ValueGraphVisitor for_true(owner());
1802 node->true_expr()->Visit(&for_true); 1722 node->true_expr()->Visit(&for_true);
1803 ASSERT(for_true.is_open()); 1723 ASSERT(for_true.is_open());
1804 for_true.Do( 1724 for_true.Do(
1805 BuildStoreExprTemp(for_true.value(), node->true_expr()->token_pos())); 1725 BuildStoreExprTemp(for_true.value(), node->true_expr()->token_pos()));
1806 1726
1807 ValueGraphVisitor for_false(owner()); 1727 ValueGraphVisitor for_false(owner());
1808 node->false_expr()->Visit(&for_false); 1728 node->false_expr()->Visit(&for_false);
1809 ASSERT(for_false.is_open()); 1729 ASSERT(for_false.is_open());
1810 for_false.Do( 1730 for_false.Do(
1811 BuildStoreExprTemp(for_false.value(), node->false_expr()->token_pos())); 1731 BuildStoreExprTemp(for_false.value(), node->false_expr()->token_pos()));
1812 1732
1813 Join(for_test, for_true, for_false); 1733 Join(for_test, for_true, for_false);
1814 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); 1734 ReturnDefinition(BuildLoadExprTemp(node->token_pos()));
1815 } 1735 }
1816 1736
1817
1818 // <Statement> ::= If { condition: <Expression> 1737 // <Statement> ::= If { condition: <Expression>
1819 // true_branch: <Sequence> 1738 // true_branch: <Sequence>
1820 // false_branch: <Sequence> } 1739 // false_branch: <Sequence> }
1821 void EffectGraphVisitor::VisitIfNode(IfNode* node) { 1740 void EffectGraphVisitor::VisitIfNode(IfNode* node) {
1822 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); 1741 TestGraphVisitor for_test(owner(), node->condition()->token_pos());
1823 node->condition()->Visit(&for_test); 1742 node->condition()->Visit(&for_test);
1824 1743
1825 EffectGraphVisitor for_true(owner()); 1744 EffectGraphVisitor for_true(owner());
1826 EffectGraphVisitor for_false(owner()); 1745 EffectGraphVisitor for_false(owner());
1827 1746
1828 node->true_branch()->Visit(&for_true); 1747 node->true_branch()->Visit(&for_true);
1829 // The for_false graph fragment will be empty (default graph fragment) if 1748 // The for_false graph fragment will be empty (default graph fragment) if
1830 // we do not call Visit. 1749 // we do not call Visit.
1831 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false); 1750 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false);
1832 Join(for_test, for_true, for_false); 1751 Join(for_test, for_true, for_false);
1833 } 1752 }
1834 1753
1835
1836 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) { 1754 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) {
1837 NestedSwitch nested_switch(owner(), node); 1755 NestedSwitch nested_switch(owner(), node);
1838 EffectGraphVisitor switch_body(owner()); 1756 EffectGraphVisitor switch_body(owner());
1839 node->body()->Visit(&switch_body); 1757 node->body()->Visit(&switch_body);
1840 Append(switch_body); 1758 Append(switch_body);
1841 if (nested_switch.break_target() != NULL) { 1759 if (nested_switch.break_target() != NULL) {
1842 if (is_open()) Goto(nested_switch.break_target()); 1760 if (is_open()) Goto(nested_switch.break_target());
1843 exit_ = nested_switch.break_target(); 1761 exit_ = nested_switch.break_target();
1844 } 1762 }
1845 } 1763 }
1846 1764
1847
1848 // A case node contains zero or more case expressions, can contain default 1765 // A case node contains zero or more case expressions, can contain default
1849 // and a case statement body. 1766 // and a case statement body.
1850 // Compose fragment as follows: 1767 // Compose fragment as follows:
1851 // - if no case expressions, must have default: 1768 // - if no case expressions, must have default:
1852 // a) target 1769 // a) target
1853 // b) [ case-statements ] 1770 // b) [ case-statements ]
1854 // 1771 //
1855 // - if has 1 or more case statements 1772 // - if has 1 or more case statements
1856 // a) target-0 1773 // a) target-0
1857 // b) [ case-expression-0 ] -> (true-target-0, target-1) 1774 // b) [ case-expression-0 ] -> (true-target-0, target-1)
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1940 // A CaseNode without case expressions must contain default. 1857 // A CaseNode without case expressions must contain default.
1941 ASSERT(node->contains_default()); 1858 ASSERT(node->contains_default());
1942 Goto(statement_start); 1859 Goto(statement_start);
1943 exit_instruction = statement_exit; 1860 exit_instruction = statement_exit;
1944 } 1861 }
1945 1862
1946 ASSERT(!is_open()); 1863 ASSERT(!is_open());
1947 exit_ = exit_instruction; 1864 exit_ = exit_instruction;
1948 } 1865 }
1949 1866
1950
1951 // <Statement> ::= While { label: SourceLabel 1867 // <Statement> ::= While { label: SourceLabel
1952 // condition: <Expression> 1868 // condition: <Expression>
1953 // body: <Sequence> } 1869 // body: <Sequence> }
1954 // The fragment is composed as follows: 1870 // The fragment is composed as follows:
1955 // a) loop-join 1871 // a) loop-join
1956 // b) [ test_preamble ]? 1872 // b) [ test_preamble ]?
1957 // c) [ test ] -> (body-entry-target, loop-exit-target) 1873 // c) [ test ] -> (body-entry-target, loop-exit-target)
1958 // d) body-entry-target 1874 // d) body-entry-target
1959 // e) [ body ] -> (continue-join) 1875 // e) [ body ] -> (continue-join)
1960 // f) continue-join -> (loop-join) 1876 // f) continue-join -> (loop-join)
(...skipping 21 matching lines...) Expand all
1982 for_body.exit_ = join; 1898 for_body.exit_ = join;
1983 } 1899 }
1984 TieLoop(node->token_pos(), for_test, for_body, for_preamble); 1900 TieLoop(node->token_pos(), for_test, for_body, for_preamble);
1985 join = nested_loop.break_target(); 1901 join = nested_loop.break_target();
1986 if (join != NULL) { 1902 if (join != NULL) {
1987 Goto(join); 1903 Goto(join);
1988 exit_ = join; 1904 exit_ = join;
1989 } 1905 }
1990 } 1906 }
1991 1907
1992
1993 // The fragment is composed as follows: 1908 // The fragment is composed as follows:
1994 // a) body-entry-join 1909 // a) body-entry-join
1995 // b) [ body ] 1910 // b) [ body ]
1996 // c) test-entry (continue-join or body-exit-target) 1911 // c) test-entry (continue-join or body-exit-target)
1997 // d) [ test-entry ] -> (back-target, loop-exit-target) 1912 // d) [ test-entry ] -> (back-target, loop-exit-target)
1998 // e) back-target -> (body-entry-join) 1913 // e) back-target -> (body-entry-join)
1999 // f) loop-exit-target 1914 // f) loop-exit-target
2000 // g) break-join 1915 // g) break-join
2001 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) { 1916 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
2002 NestedLoop nested_loop(owner(), node->label()); 1917 NestedLoop nested_loop(owner(), node->label());
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2035 for_test.IfTrueGoto(body_entry_join); 1950 for_test.IfTrueGoto(body_entry_join);
2036 join = nested_loop.break_target(); 1951 join = nested_loop.break_target();
2037 if (join == NULL) { 1952 if (join == NULL) {
2038 exit_ = for_test.CreateFalseSuccessor(); 1953 exit_ = for_test.CreateFalseSuccessor();
2039 } else { 1954 } else {
2040 for_test.IfFalseGoto(join); 1955 for_test.IfFalseGoto(join);
2041 exit_ = join; 1956 exit_ = join;
2042 } 1957 }
2043 } 1958 }
2044 1959
2045
2046 // A ForNode can contain break and continue jumps. 'break' joins to 1960 // A ForNode can contain break and continue jumps. 'break' joins to
2047 // ForNode exit, 'continue' joins at increment entry. The fragment is composed 1961 // ForNode exit, 'continue' joins at increment entry. The fragment is composed
2048 // as follows: 1962 // as follows:
2049 // a) [ initializer ] 1963 // a) [ initializer ]
2050 // b) loop-join 1964 // b) loop-join
2051 // c) [ test ] -> (body-entry-target, loop-exit-target) 1965 // c) [ test ] -> (body-entry-target, loop-exit-target)
2052 // d) body-entry-target 1966 // d) body-entry-target
2053 // e) [ body ] 1967 // e) [ body ]
2054 // f) continue-join (optional) 1968 // f) continue-join (optional)
2055 // g) [ increment ] -> (loop-join) 1969 // g) [ increment ] -> (loop-join)
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2115 2029
2116 if (nested_loop.break_target() == NULL) { 2030 if (nested_loop.break_target() == NULL) {
2117 exit_ = for_test.CreateFalseSuccessor(); 2031 exit_ = for_test.CreateFalseSuccessor();
2118 } else { 2032 } else {
2119 for_test.IfFalseGoto(nested_loop.break_target()); 2033 for_test.IfFalseGoto(nested_loop.break_target());
2120 exit_ = nested_loop.break_target(); 2034 exit_ = nested_loop.break_target();
2121 } 2035 }
2122 } 2036 }
2123 } 2037 }
2124 2038
2125
2126 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) { 2039 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) {
2127 if (FLAG_support_debugger && owner()->function().is_debuggable()) { 2040 if (FLAG_support_debugger && owner()->function().is_debuggable()) {
2128 AddInstruction(new (Z) DebugStepCheckInstr(node->token_pos(), 2041 AddInstruction(new (Z) DebugStepCheckInstr(node->token_pos(),
2129 RawPcDescriptors::kRuntimeCall, 2042 RawPcDescriptors::kRuntimeCall,
2130 owner()->GetNextDeoptId())); 2043 owner()->GetNextDeoptId()));
2131 } 2044 }
2132 2045
2133 NestedContextAdjustment context_adjustment(owner(), owner()->context_level()); 2046 NestedContextAdjustment context_adjustment(owner(), owner()->context_level());
2134 2047
2135 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { 2048 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
(...skipping 15 matching lines...) Expand all
2151 jump_target = (node->kind() == Token::kBREAK) 2064 jump_target = (node->kind() == Token::kBREAK)
2152 ? current->BreakTargetFor(node->label()) 2065 ? current->BreakTargetFor(node->label())
2153 : current->ContinueTargetFor(node->label()); 2066 : current->ContinueTargetFor(node->label());
2154 if (jump_target != NULL) break; 2067 if (jump_target != NULL) break;
2155 current = current->outer(); 2068 current = current->outer();
2156 } 2069 }
2157 ASSERT(jump_target != NULL); 2070 ASSERT(jump_target != NULL);
2158 Goto(jump_target); 2071 Goto(jump_target);
2159 } 2072 }
2160 2073
2161
2162 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) { 2074 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
2163 UNREACHABLE(); 2075 UNREACHABLE();
2164 } 2076 }
2165 2077
2166
2167 void EffectGraphVisitor::VisitAwaitNode(AwaitNode* node) { 2078 void EffectGraphVisitor::VisitAwaitNode(AwaitNode* node) {
2168 // Await nodes are temporary during parsing. 2079 // Await nodes are temporary during parsing.
2169 UNREACHABLE(); 2080 UNREACHABLE();
2170 } 2081 }
2171 2082
2172
2173 void EffectGraphVisitor::VisitAwaitMarkerNode(AwaitMarkerNode* node) { 2083 void EffectGraphVisitor::VisitAwaitMarkerNode(AwaitMarkerNode* node) {
2174 // We need to create a new await state which involves: 2084 // We need to create a new await state which involves:
2175 // * Increase the jump counter. Sanity check against the list of targets. 2085 // * Increase the jump counter. Sanity check against the list of targets.
2176 // * Save the current context for resuming. 2086 // * Save the current context for resuming.
2177 ASSERT(node->token_pos().IsSynthetic() || node->token_pos().IsNoSource()); 2087 ASSERT(node->token_pos().IsSynthetic() || node->token_pos().IsNoSource());
2178 ASSERT(node->async_scope() != NULL); 2088 ASSERT(node->async_scope() != NULL);
2179 ASSERT(node->await_scope() != NULL); 2089 ASSERT(node->await_scope() != NULL);
2180 LocalVariable* jump_var = 2090 LocalVariable* jump_var =
2181 node->async_scope()->LookupVariable(Symbols::AwaitJumpVar(), false); 2091 node->async_scope()->LookupVariable(Symbols::AwaitJumpVar(), false);
2182 LocalVariable* ctx_var = 2092 LocalVariable* ctx_var =
2183 node->async_scope()->LookupVariable(Symbols::AwaitContextVar(), false); 2093 node->async_scope()->LookupVariable(Symbols::AwaitContextVar(), false);
2184 ASSERT((jump_var != NULL) && jump_var->is_captured()); 2094 ASSERT((jump_var != NULL) && jump_var->is_captured());
2185 ASSERT((ctx_var != NULL) && ctx_var->is_captured()); 2095 ASSERT((ctx_var != NULL) && ctx_var->is_captured());
2186 const intptr_t jump_count = owner()->next_await_counter(); 2096 const intptr_t jump_count = owner()->next_await_counter();
2187 ASSERT(jump_count >= 0); 2097 ASSERT(jump_count >= 0);
2188 // Sanity check that we always add a JoinEntryInstr before adding a new 2098 // Sanity check that we always add a JoinEntryInstr before adding a new
2189 // state. 2099 // state.
2190 ASSERT(jump_count == owner()->await_joins()->length()); 2100 ASSERT(jump_count == owner()->await_joins()->length());
2191 // Store the counter in :await_jump_var. 2101 // Store the counter in :await_jump_var.
2192 Value* jump_val = Bind(new (Z) ConstantInstr( 2102 Value* jump_val = Bind(new (Z) ConstantInstr(
2193 Smi::ZoneHandle(Z, Smi::New(jump_count)), node->token_pos())); 2103 Smi::ZoneHandle(Z, Smi::New(jump_count)), node->token_pos()));
2194 Do(BuildStoreLocal(*jump_var, jump_val, node->token_pos())); 2104 Do(BuildStoreLocal(*jump_var, jump_val, node->token_pos()));
2195 // Add a mapping from jump_count -> token_position. 2105 // Add a mapping from jump_count -> token_position.
2196 owner()->AppendAwaitTokenPosition(node->token_pos()); 2106 owner()->AppendAwaitTokenPosition(node->token_pos());
2197 // Save the current context for resuming. 2107 // Save the current context for resuming.
2198 BuildSaveContext(*ctx_var, node->token_pos()); 2108 BuildSaveContext(*ctx_var, node->token_pos());
2199 } 2109 }
2200 2110
2201
2202 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { 2111 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const {
2203 return kFirstLocalSlotFromFp - owner()->num_stack_locals() - 2112 return kFirstLocalSlotFromFp - owner()->num_stack_locals() -
2204 owner()->num_copied_params() - owner()->args_pushed() - 2113 owner()->num_copied_params() - owner()->args_pushed() -
2205 owner()->temp_count() + 1; 2114 owner()->temp_count() + 1;
2206 } 2115 }
2207 2116
2208
2209 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) { 2117 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) {
2210 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1)); 2118 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1));
2211 intptr_t index = GetCurrentTempLocalIndex(); 2119 intptr_t index = GetCurrentTempLocalIndex();
2212 char name[64]; 2120 char name[64];
2213 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); 2121 OS::SNPrint(name, 64, ":tmp_local%" Pd, index);
2214 LocalVariable* var = 2122 LocalVariable* var =
2215 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, 2123 new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
2216 String::ZoneHandle(Z, Symbols::New(T, name)), 2124 String::ZoneHandle(Z, Symbols::New(T, name)),
2217 *value->Type()->ToAbstractType()); 2125 *value->Type()->ToAbstractType());
2218 var->set_index(index); 2126 var->set_index(index);
2219 return var; 2127 return var;
2220 } 2128 }
2221 2129
2222
2223 Definition* EffectGraphVisitor::ExitTempLocalScope(Value* value) { 2130 Definition* EffectGraphVisitor::ExitTempLocalScope(Value* value) {
2224 return new (Z) DropTempsInstr(0, value); 2131 return new (Z) DropTempsInstr(0, value);
2225 } 2132 }
2226 2133
2227
2228 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { 2134 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) {
2229 intptr_t num_temps = node->num_temps(); 2135 intptr_t num_temps = node->num_temps();
2230 for (intptr_t i = 0; i < num_temps; ++i) { 2136 for (intptr_t i = 0; i < num_temps; ++i) {
2231 ValueGraphVisitor for_value(owner()); 2137 ValueGraphVisitor for_value(owner());
2232 node->InitializerAt(i)->Visit(&for_value); 2138 node->InitializerAt(i)->Visit(&for_value);
2233 Append(for_value); 2139 Append(for_value);
2234 ASSERT(!node->TempAt(i)->HasIndex() || 2140 ASSERT(!node->TempAt(i)->HasIndex() ||
2235 (node->TempAt(i)->index() == GetCurrentTempLocalIndex())); 2141 (node->TempAt(i)->index() == GetCurrentTempLocalIndex()));
2236 node->TempAt(i)->set_index(GetCurrentTempLocalIndex()); 2142 node->TempAt(i)->set_index(GetCurrentTempLocalIndex());
2237 } 2143 }
2238 } 2144 }
2239 2145
2240
2241 void EffectGraphVisitor::VisitLetNode(LetNode* node) { 2146 void EffectGraphVisitor::VisitLetNode(LetNode* node) {
2242 BuildLetTempExpressions(node); 2147 BuildLetTempExpressions(node);
2243 2148
2244 // Visit body. 2149 // Visit body.
2245 for (intptr_t i = 0; i < node->nodes().length(); ++i) { 2150 for (intptr_t i = 0; i < node->nodes().length(); ++i) {
2246 EffectGraphVisitor for_effect(owner()); 2151 EffectGraphVisitor for_effect(owner());
2247 node->nodes()[i]->Visit(&for_effect); 2152 node->nodes()[i]->Visit(&for_effect);
2248 Append(for_effect); 2153 Append(for_effect);
2249 } 2154 }
2250 2155
2251 intptr_t num_temps = node->num_temps(); 2156 intptr_t num_temps = node->num_temps();
2252 if (num_temps > 0) { 2157 if (num_temps > 0) {
2253 owner()->DeallocateTemps(num_temps); 2158 owner()->DeallocateTemps(num_temps);
2254 Do(new (Z) DropTempsInstr(num_temps, NULL)); 2159 Do(new (Z) DropTempsInstr(num_temps, NULL));
2255 } 2160 }
2256 } 2161 }
2257 2162
2258
2259 void ValueGraphVisitor::VisitLetNode(LetNode* node) { 2163 void ValueGraphVisitor::VisitLetNode(LetNode* node) {
2260 BuildLetTempExpressions(node); 2164 BuildLetTempExpressions(node);
2261 2165
2262 // Visit body. 2166 // Visit body.
2263 for (intptr_t i = 0; i < node->nodes().length() - 1; ++i) { 2167 for (intptr_t i = 0; i < node->nodes().length() - 1; ++i) {
2264 EffectGraphVisitor for_effect(owner()); 2168 EffectGraphVisitor for_effect(owner());
2265 node->nodes()[i]->Visit(&for_effect); 2169 node->nodes()[i]->Visit(&for_effect);
2266 Append(for_effect); 2170 Append(for_effect);
2267 } 2171 }
2268 // Visit the last body expression for value. 2172 // Visit the last body expression for value.
2269 ValueGraphVisitor for_value(owner()); 2173 ValueGraphVisitor for_value(owner());
2270 node->nodes().Last()->Visit(&for_value); 2174 node->nodes().Last()->Visit(&for_value);
2271 Append(for_value); 2175 Append(for_value);
2272 Value* result_value = for_value.value(); 2176 Value* result_value = for_value.value();
2273 2177
2274 intptr_t num_temps = node->num_temps(); 2178 intptr_t num_temps = node->num_temps();
2275 if (num_temps > 0) { 2179 if (num_temps > 0) {
2276 owner()->DeallocateTemps(num_temps); 2180 owner()->DeallocateTemps(num_temps);
2277 ReturnDefinition(new (Z) DropTempsInstr(num_temps, result_value)); 2181 ReturnDefinition(new (Z) DropTempsInstr(num_temps, result_value));
2278 } else { 2182 } else {
2279 ReturnValue(result_value); 2183 ReturnValue(result_value);
2280 } 2184 }
2281 } 2185 }
2282 2186
2283
2284 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { 2187 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
2285 const TypeArguments& type_args = 2188 const TypeArguments& type_args =
2286 TypeArguments::ZoneHandle(Z, node->type().arguments()); 2189 TypeArguments::ZoneHandle(Z, node->type().arguments());
2287 Value* element_type = 2190 Value* element_type =
2288 BuildInstantiatedTypeArguments(node->token_pos(), type_args); 2191 BuildInstantiatedTypeArguments(node->token_pos(), type_args);
2289 Value* num_elements = 2192 Value* num_elements =
2290 Bind(new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(node->length())))); 2193 Bind(new (Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(node->length()))));
2291 CreateArrayInstr* create = new (Z) CreateArrayInstr( 2194 CreateArrayInstr* create = new (Z) CreateArrayInstr(
2292 node->token_pos(), element_type, num_elements, owner()->GetNextDeoptId()); 2195 node->token_pos(), element_type, num_elements, owner()->GetNextDeoptId());
2293 Value* array_val = Bind(create); 2196 Value* array_val = Bind(create);
(...skipping 16 matching lines...) Expand all
2310 const intptr_t index_scale = Instance::ElementSizeFor(class_id); 2213 const intptr_t index_scale = Instance::ElementSizeFor(class_id);
2311 StoreIndexedInstr* store = new (Z) StoreIndexedInstr( 2214 StoreIndexedInstr* store = new (Z) StoreIndexedInstr(
2312 array, index, for_value.value(), emit_store_barrier, index_scale, 2215 array, index, for_value.value(), emit_store_barrier, index_scale,
2313 class_id, kAlignedAccess, deopt_id, node->token_pos()); 2216 class_id, kAlignedAccess, deopt_id, node->token_pos());
2314 Do(store); 2217 Do(store);
2315 } 2218 }
2316 ReturnDefinition(ExitTempLocalScope(array_val)); 2219 ReturnDefinition(ExitTempLocalScope(array_val));
2317 } 2220 }
2318 } 2221 }
2319 2222
2320
2321 void EffectGraphVisitor::VisitStringInterpolateNode( 2223 void EffectGraphVisitor::VisitStringInterpolateNode(
2322 StringInterpolateNode* node) { 2224 StringInterpolateNode* node) {
2323 ValueGraphVisitor for_argument(owner()); 2225 ValueGraphVisitor for_argument(owner());
2324 ArrayNode* arguments = node->value(); 2226 ArrayNode* arguments = node->value();
2325 if (arguments->length() == 1) { 2227 if (arguments->length() == 1) {
2326 ZoneGrowableArray<PushArgumentInstr*>* values = 2228 ZoneGrowableArray<PushArgumentInstr*>* values =
2327 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1); 2229 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1);
2328 arguments->ElementAt(0)->Visit(&for_argument); 2230 arguments->ElementAt(0)->Visit(&for_argument);
2329 Append(for_argument); 2231 Append(for_argument);
2330 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); 2232 PushArgumentInstr* push_arg = PushArgument(for_argument.value());
(...skipping 14 matching lines...) Expand all
2345 ReturnDefinition(call); 2247 ReturnDefinition(call);
2346 return; 2248 return;
2347 } 2249 }
2348 arguments->Visit(&for_argument); 2250 arguments->Visit(&for_argument);
2349 Append(for_argument); 2251 Append(for_argument);
2350 StringInterpolateInstr* instr = new (Z) StringInterpolateInstr( 2252 StringInterpolateInstr* instr = new (Z) StringInterpolateInstr(
2351 for_argument.value(), node->token_pos(), owner()->GetNextDeoptId()); 2253 for_argument.value(), node->token_pos(), owner()->GetNextDeoptId());
2352 ReturnDefinition(instr); 2254 ReturnDefinition(instr);
2353 } 2255 }
2354 2256
2355
2356 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { 2257 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
2357 const Function& function = node->function(); 2258 const Function& function = node->function();
2358 if (function.IsImplicitStaticClosureFunction()) { 2259 if (function.IsImplicitStaticClosureFunction()) {
2359 const Instance& closure = 2260 const Instance& closure =
2360 Instance::ZoneHandle(Z, function.ImplicitStaticClosure()); 2261 Instance::ZoneHandle(Z, function.ImplicitStaticClosure());
2361 ReturnDefinition(new (Z) ConstantInstr(closure)); 2262 ReturnDefinition(new (Z) ConstantInstr(closure));
2362 return; 2263 return;
2363 } 2264 }
2364 2265
2365 const bool is_implicit = function.IsImplicitInstanceClosureFunction(); 2266 const bool is_implicit = function.IsImplicitInstanceClosureFunction();
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
2464 Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); 2365 Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos()));
2465 Value* context = Bind(BuildCurrentContext(node->token_pos())); 2366 Value* context = Bind(BuildCurrentContext(node->token_pos()));
2466 Do(new (Z) StoreInstanceFieldInstr(Closure::context_offset(), 2367 Do(new (Z) StoreInstanceFieldInstr(Closure::context_offset(),
2467 closure_tmp_val, context, 2368 closure_tmp_val, context,
2468 kEmitStoreBarrier, node->token_pos())); 2369 kEmitStoreBarrier, node->token_pos()));
2469 } 2370 }
2470 ReturnDefinition(ExitTempLocalScope(closure_val)); 2371 ReturnDefinition(ExitTempLocalScope(closure_val));
2471 } 2372 }
2472 } 2373 }
2473 2374
2474
2475 void EffectGraphVisitor::BuildPushTypeArguments( 2375 void EffectGraphVisitor::BuildPushTypeArguments(
2476 const ArgumentListNode& node, 2376 const ArgumentListNode& node,
2477 ZoneGrowableArray<PushArgumentInstr*>* values) { 2377 ZoneGrowableArray<PushArgumentInstr*>* values) {
2478 if (node.type_args_len() > 0) { 2378 if (node.type_args_len() > 0) {
2479 Value* type_args_val; 2379 Value* type_args_val;
2480 if (node.type_args_var() != NULL) { 2380 if (node.type_args_var() != NULL) {
2481 type_args_val = 2381 type_args_val =
2482 Bind(new (Z) LoadLocalInstr(*node.type_args_var(), node.token_pos())); 2382 Bind(new (Z) LoadLocalInstr(*node.type_args_var(), node.token_pos()));
2483 } else { 2383 } else {
2484 const TypeArguments& type_args = node.type_arguments(); 2384 const TypeArguments& type_args = node.type_arguments();
2485 ASSERT(!type_args.IsNull() && type_args.IsCanonical() && 2385 ASSERT(!type_args.IsNull() && type_args.IsCanonical() &&
2486 (type_args.Length() == node.type_args_len())); 2386 (type_args.Length() == node.type_args_len()));
2487 type_args_val = 2387 type_args_val =
2488 BuildInstantiatedTypeArguments(node.token_pos(), type_args); 2388 BuildInstantiatedTypeArguments(node.token_pos(), type_args);
2489 } 2389 }
2490 PushArgumentInstr* push_type_args = PushArgument(type_args_val); 2390 PushArgumentInstr* push_type_args = PushArgument(type_args_val);
2491 values->Add(push_type_args); 2391 values->Add(push_type_args);
2492 } 2392 }
2493 } 2393 }
2494 2394
2495
2496 void EffectGraphVisitor::BuildPushArguments( 2395 void EffectGraphVisitor::BuildPushArguments(
2497 const ArgumentListNode& node, 2396 const ArgumentListNode& node,
2498 ZoneGrowableArray<PushArgumentInstr*>* values) { 2397 ZoneGrowableArray<PushArgumentInstr*>* values) {
2499 for (intptr_t i = 0; i < node.length(); ++i) { 2398 for (intptr_t i = 0; i < node.length(); ++i) {
2500 ValueGraphVisitor for_argument(owner()); 2399 ValueGraphVisitor for_argument(owner());
2501 node.NodeAt(i)->Visit(&for_argument); 2400 node.NodeAt(i)->Visit(&for_argument);
2502 Append(for_argument); 2401 Append(for_argument);
2503 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); 2402 PushArgumentInstr* push_arg = PushArgument(for_argument.value());
2504 values->Add(push_arg); 2403 values->Add(push_arg);
2505 } 2404 }
2506 } 2405 }
2507 2406
2508
2509 void EffectGraphVisitor::BuildInstanceCallConditional(InstanceCallNode* node) { 2407 void EffectGraphVisitor::BuildInstanceCallConditional(InstanceCallNode* node) {
2510 const TokenPosition token_pos = node->token_pos(); 2408 const TokenPosition token_pos = node->token_pos();
2511 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); 2409 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
2512 LoadLocalNode* load_temp = new (Z) LoadLocalNode(token_pos, temp_var); 2410 LoadLocalNode* load_temp = new (Z) LoadLocalNode(token_pos, temp_var);
2513 2411
2514 LiteralNode* null_constant = 2412 LiteralNode* null_constant =
2515 new (Z) LiteralNode(ST(token_pos), Object::null_instance()); 2413 new (Z) LiteralNode(ST(token_pos), Object::null_instance());
2516 ComparisonNode* check_is_null = new (Z) 2414 ComparisonNode* check_is_null = new (Z)
2517 ComparisonNode(ST(token_pos), Token::kEQ, load_temp, null_constant); 2415 ComparisonNode(ST(token_pos), Token::kEQ, load_temp, null_constant);
2518 TestGraphVisitor for_test(owner(), ST(token_pos)); 2416 TestGraphVisitor for_test(owner(), ST(token_pos));
2519 check_is_null->Visit(&for_test); 2417 check_is_null->Visit(&for_test);
2520 2418
2521 EffectGraphVisitor for_true(owner()); 2419 EffectGraphVisitor for_true(owner());
2522 EffectGraphVisitor for_false(owner()); 2420 EffectGraphVisitor for_false(owner());
2523 2421
2524 StoreLocalNode* store_null = 2422 StoreLocalNode* store_null =
2525 new (Z) StoreLocalNode(ST(token_pos), temp_var, null_constant); 2423 new (Z) StoreLocalNode(ST(token_pos), temp_var, null_constant);
2526 store_null->Visit(&for_true); 2424 store_null->Visit(&for_true);
2527 2425
2528 InstanceCallNode* call = new (Z) InstanceCallNode( 2426 InstanceCallNode* call = new (Z) InstanceCallNode(
2529 token_pos, load_temp, node->function_name(), node->arguments()); 2427 token_pos, load_temp, node->function_name(), node->arguments());
2530 StoreLocalNode* store_result = 2428 StoreLocalNode* store_result =
2531 new (Z) StoreLocalNode(ST(token_pos), temp_var, call); 2429 new (Z) StoreLocalNode(ST(token_pos), temp_var, call);
2532 store_result->Visit(&for_false); 2430 store_result->Visit(&for_false);
2533 2431
2534 Join(for_test, for_true, for_false); 2432 Join(for_test, for_true, for_false);
2535 } 2433 }
2536 2434
2537
2538 void ValueGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { 2435 void ValueGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
2539 if (node->is_conditional()) { 2436 if (node->is_conditional()) {
2540 ValueGraphVisitor for_receiver(owner()); 2437 ValueGraphVisitor for_receiver(owner());
2541 node->receiver()->Visit(&for_receiver); 2438 node->receiver()->Visit(&for_receiver);
2542 Append(for_receiver); 2439 Append(for_receiver);
2543 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos())); 2440 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos()));
2544 BuildInstanceCallConditional(node); 2441 BuildInstanceCallConditional(node);
2545 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); 2442 ReturnDefinition(BuildLoadExprTemp(node->token_pos()));
2546 } else { 2443 } else {
2547 EffectGraphVisitor::VisitInstanceCallNode(node); 2444 EffectGraphVisitor::VisitInstanceCallNode(node);
2548 } 2445 }
2549 } 2446 }
2550 2447
2551
2552 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { 2448 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
2553 if (node->is_conditional()) { 2449 if (node->is_conditional()) {
2554 ASSERT(node->arguments()->type_args_len() == 0); 2450 ASSERT(node->arguments()->type_args_len() == 0);
2555 ValueGraphVisitor for_receiver(owner()); 2451 ValueGraphVisitor for_receiver(owner());
2556 node->receiver()->Visit(&for_receiver); 2452 node->receiver()->Visit(&for_receiver);
2557 Append(for_receiver); 2453 Append(for_receiver);
2558 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos())); 2454 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos()));
2559 BuildInstanceCallConditional(node); 2455 BuildInstanceCallConditional(node);
2560 } else { 2456 } else {
2561 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2457 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2562 new (Z) ZoneGrowableArray<PushArgumentInstr*>( 2458 new (Z) ZoneGrowableArray<PushArgumentInstr*>(
2563 node->arguments()->LengthWithTypeArgs() + 1); 2459 node->arguments()->LengthWithTypeArgs() + 1);
2564 BuildPushTypeArguments(*node->arguments(), arguments); 2460 BuildPushTypeArguments(*node->arguments(), arguments);
2565 ValueGraphVisitor for_receiver(owner()); 2461 ValueGraphVisitor for_receiver(owner());
2566 node->receiver()->Visit(&for_receiver); 2462 node->receiver()->Visit(&for_receiver);
2567 Append(for_receiver); 2463 Append(for_receiver);
2568 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 2464 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
2569 arguments->Add(push_receiver); 2465 arguments->Add(push_receiver);
2570 BuildPushArguments(*node->arguments(), arguments); 2466 BuildPushArguments(*node->arguments(), arguments);
2571 InstanceCallInstr* call = new (Z) InstanceCallInstr( 2467 InstanceCallInstr* call = new (Z) InstanceCallInstr(
2572 node->token_pos(), node->function_name(), Token::kILLEGAL, arguments, 2468 node->token_pos(), node->function_name(), Token::kILLEGAL, arguments,
2573 node->arguments()->type_args_len(), node->arguments()->names(), 1, 2469 node->arguments()->type_args_len(), node->arguments()->names(), 1,
2574 owner()->ic_data_array(), owner()->GetNextDeoptId()); 2470 owner()->ic_data_array(), owner()->GetNextDeoptId());
2575 ReturnDefinition(call); 2471 ReturnDefinition(call);
2576 } 2472 }
2577 } 2473 }
2578 2474
2579
2580 // <Expression> ::= StaticCall { function: Function 2475 // <Expression> ::= StaticCall { function: Function
2581 // arguments: <ArgumentList> } 2476 // arguments: <ArgumentList> }
2582 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) { 2477 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
2583 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2478 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2584 new (Z) ZoneGrowableArray<PushArgumentInstr*>( 2479 new (Z) ZoneGrowableArray<PushArgumentInstr*>(
2585 node->arguments()->LengthWithTypeArgs()); 2480 node->arguments()->LengthWithTypeArgs());
2586 BuildPushTypeArguments(*node->arguments(), arguments); 2481 BuildPushTypeArguments(*node->arguments(), arguments);
2587 BuildPushArguments(*node->arguments(), arguments); 2482 BuildPushArguments(*node->arguments(), arguments);
2588 StaticCallInstr* call = new (Z) StaticCallInstr( 2483 StaticCallInstr* call = new (Z) StaticCallInstr(
2589 node->token_pos(), node->function(), node->arguments()->type_args_len(), 2484 node->token_pos(), node->function(), node->arguments()->type_args_len(),
2590 node->arguments()->names(), arguments, owner()->ic_data_array(), 2485 node->arguments()->names(), arguments, owner()->ic_data_array(),
2591 owner()->GetNextDeoptId()); 2486 owner()->GetNextDeoptId());
2592 if (node->function().recognized_kind() != MethodRecognizer::kUnknown) { 2487 if (node->function().recognized_kind() != MethodRecognizer::kUnknown) {
2593 call->set_result_cid(MethodRecognizer::ResultCid(node->function())); 2488 call->set_result_cid(MethodRecognizer::ResultCid(node->function()));
2594 } 2489 }
2595 ReturnDefinition(call); 2490 ReturnDefinition(call);
2596 } 2491 }
2597 2492
2598
2599 void EffectGraphVisitor::BuildClosureCall(ClosureCallNode* node, 2493 void EffectGraphVisitor::BuildClosureCall(ClosureCallNode* node,
2600 bool result_needed) { 2494 bool result_needed) {
2601 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2495 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2602 new (Z) ZoneGrowableArray<PushArgumentInstr*>( 2496 new (Z) ZoneGrowableArray<PushArgumentInstr*>(
2603 node->arguments()->LengthWithTypeArgs() + 1); 2497 node->arguments()->LengthWithTypeArgs() + 1);
2604 2498
2605 ValueGraphVisitor for_closure(owner()); 2499 ValueGraphVisitor for_closure(owner());
2606 node->closure()->Visit(&for_closure); 2500 node->closure()->Visit(&for_closure);
2607 Append(for_closure); 2501 Append(for_closure);
2608 Value* closure_value = for_closure.value(); 2502 Value* closure_value = for_closure.value();
(...skipping 17 matching lines...) Expand all
2626 function_val, node, arguments, owner()->GetNextDeoptId()); 2520 function_val, node, arguments, owner()->GetNextDeoptId());
2627 if (result_needed) { 2521 if (result_needed) {
2628 Value* result = Bind(closure_call); 2522 Value* result = Bind(closure_call);
2629 Do(new (Z) StoreLocalInstr(*tmp_var, result, ST(node->token_pos()))); 2523 Do(new (Z) StoreLocalInstr(*tmp_var, result, ST(node->token_pos())));
2630 } else { 2524 } else {
2631 Do(closure_call); 2525 Do(closure_call);
2632 } 2526 }
2633 ReturnDefinition(ExitTempLocalScope(closure_value)); 2527 ReturnDefinition(ExitTempLocalScope(closure_value));
2634 } 2528 }
2635 2529
2636
2637 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 2530 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
2638 BuildClosureCall(node, false); 2531 BuildClosureCall(node, false);
2639 } 2532 }
2640 2533
2641
2642 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 2534 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
2643 BuildClosureCall(node, true); 2535 BuildClosureCall(node, true);
2644 } 2536 }
2645 2537
2646
2647 void EffectGraphVisitor::VisitInitStaticFieldNode(InitStaticFieldNode* node) { 2538 void EffectGraphVisitor::VisitInitStaticFieldNode(InitStaticFieldNode* node) {
2648 Value* field = Bind( 2539 Value* field = Bind(
2649 new (Z) ConstantInstr(Field::ZoneHandle(Z, node->field().Original()))); 2540 new (Z) ConstantInstr(Field::ZoneHandle(Z, node->field().Original())));
2650 AddInstruction(new (Z) InitStaticFieldInstr(field, node->field(), 2541 AddInstruction(new (Z) InitStaticFieldInstr(field, node->field(),
2651 owner()->GetNextDeoptId())); 2542 owner()->GetNextDeoptId()));
2652 } 2543 }
2653 2544
2654
2655 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { 2545 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
2656 Value* context = Bind(BuildCurrentContext(node->token_pos())); 2546 Value* context = Bind(BuildCurrentContext(node->token_pos()));
2657 Value* clone = Bind(new (Z) CloneContextInstr(node->token_pos(), context, 2547 Value* clone = Bind(new (Z) CloneContextInstr(node->token_pos(), context,
2658 owner()->GetNextDeoptId())); 2548 owner()->GetNextDeoptId()));
2659 Do(BuildStoreContext(clone, node->token_pos())); 2549 Do(BuildStoreContext(clone, node->token_pos()));
2660 } 2550 }
2661 2551
2662
2663 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) { 2552 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) {
2664 const Class& cls = Class::ZoneHandle(Z, node->constructor().Owner()); 2553 const Class& cls = Class::ZoneHandle(Z, node->constructor().Owner());
2665 const bool cls_is_parameterized = cls.NumTypeArguments() > 0; 2554 const bool cls_is_parameterized = cls.NumTypeArguments() > 0;
2666 2555
2667 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = new (Z) 2556 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = new (Z)
2668 ZoneGrowableArray<PushArgumentInstr*>(cls_is_parameterized ? 1 : 0); 2557 ZoneGrowableArray<PushArgumentInstr*>(cls_is_parameterized ? 1 : 0);
2669 if (cls_is_parameterized) { 2558 if (cls_is_parameterized) {
2670 Value* type_args = BuildInstantiatedTypeArguments(node->token_pos(), 2559 Value* type_args = BuildInstantiatedTypeArguments(node->token_pos(),
2671 node->type_arguments()); 2560 node->type_arguments());
2672 allocate_arguments->Add(PushArgument(type_args)); 2561 allocate_arguments->Add(PushArgument(type_args));
2673 } 2562 }
2674 2563
2675 Definition* allocation = new (Z) AllocateObjectInstr( 2564 Definition* allocation = new (Z) AllocateObjectInstr(
2676 node->token_pos(), Class::ZoneHandle(Z, node->constructor().Owner()), 2565 node->token_pos(), Class::ZoneHandle(Z, node->constructor().Owner()),
2677 allocate_arguments); 2566 allocate_arguments);
2678 2567
2679 return Bind(allocation); 2568 return Bind(allocation);
2680 } 2569 }
2681 2570
2682
2683 void EffectGraphVisitor::BuildConstructorCall( 2571 void EffectGraphVisitor::BuildConstructorCall(
2684 ConstructorCallNode* node, 2572 ConstructorCallNode* node,
2685 PushArgumentInstr* push_alloc_value) { 2573 PushArgumentInstr* push_alloc_value) {
2686 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2574 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2687 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2); 2575 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
2688 arguments->Add(push_alloc_value); 2576 arguments->Add(push_alloc_value);
2689 2577
2690 BuildPushArguments(*node->arguments(), arguments); 2578 BuildPushArguments(*node->arguments(), arguments);
2691 const intptr_t kTypeArgsLen = 0; 2579 const intptr_t kTypeArgsLen = 0;
2692 Do(new (Z) 2580 Do(new (Z)
2693 StaticCallInstr(node->token_pos(), node->constructor(), kTypeArgsLen, 2581 StaticCallInstr(node->token_pos(), node->constructor(), kTypeArgsLen,
2694 node->arguments()->names(), arguments, 2582 node->arguments()->names(), arguments,
2695 owner()->ic_data_array(), owner()->GetNextDeoptId())); 2583 owner()->ic_data_array(), owner()->GetNextDeoptId()));
2696 } 2584 }
2697 2585
2698
2699 static intptr_t GetResultCidOfListFactory(ConstructorCallNode* node) { 2586 static intptr_t GetResultCidOfListFactory(ConstructorCallNode* node) {
2700 const Function& function = node->constructor(); 2587 const Function& function = node->constructor();
2701 const Class& function_class = Class::Handle(function.Owner()); 2588 const Class& function_class = Class::Handle(function.Owner());
2702 2589
2703 if ((function_class.library() != Library::CoreLibrary()) && 2590 if ((function_class.library() != Library::CoreLibrary()) &&
2704 (function_class.library() != Library::TypedDataLibrary())) { 2591 (function_class.library() != Library::TypedDataLibrary())) {
2705 return kDynamicCid; 2592 return kDynamicCid;
2706 } 2593 }
2707 2594
2708 if (node->constructor().IsFactory()) { 2595 if (node->constructor().IsFactory()) {
2709 if ((function_class.Name() == Symbols::List().raw()) && 2596 if ((function_class.Name() == Symbols::List().raw()) &&
2710 (function.name() == Symbols::ListFactory().raw())) { 2597 (function.name() == Symbols::ListFactory().raw())) {
2711 // Special recognition of 'new List()' vs 'new List(n)'. 2598 // Special recognition of 'new List()' vs 'new List(n)'.
2712 if (node->arguments()->length() == 0) { 2599 if (node->arguments()->length() == 0) {
2713 return kGrowableObjectArrayCid; 2600 return kGrowableObjectArrayCid;
2714 } 2601 }
2715 return kArrayCid; 2602 return kArrayCid;
2716 } 2603 }
2717 return FactoryRecognizer::ResultCid(function); 2604 return FactoryRecognizer::ResultCid(function);
2718 } 2605 }
2719 return kDynamicCid; // Not a known list constructor. 2606 return kDynamicCid; // Not a known list constructor.
2720 } 2607 }
2721 2608
2722
2723 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 2609 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
2724 if (node->constructor().IsFactory()) { 2610 if (node->constructor().IsFactory()) {
2725 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2611 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2726 new (Z) ZoneGrowableArray<PushArgumentInstr*>(); 2612 new (Z) ZoneGrowableArray<PushArgumentInstr*>();
2727 PushArgumentInstr* push_type_arguments = 2613 PushArgumentInstr* push_type_arguments =
2728 PushArgument(BuildInstantiatedTypeArguments(node->token_pos(), 2614 PushArgument(BuildInstantiatedTypeArguments(node->token_pos(),
2729 node->type_arguments())); 2615 node->type_arguments()));
2730 arguments->Add(push_type_arguments); 2616 arguments->Add(push_type_arguments);
2731 ASSERT(arguments->length() == 1); 2617 ASSERT(arguments->length() == 1);
2732 BuildPushArguments(*node->arguments(), arguments); 2618 BuildPushArguments(*node->arguments(), arguments);
(...skipping 21 matching lines...) Expand all
2754 // t_n <- AllocateObject(class) 2640 // t_n <- AllocateObject(class)
2755 // t_n+1 <- ctor-arg 2641 // t_n+1 <- ctor-arg
2756 // t_n+2... <- constructor arguments start here 2642 // t_n+2... <- constructor arguments start here
2757 // StaticCall(constructor, t_n+1, t_n+2, ...) 2643 // StaticCall(constructor, t_n+1, t_n+2, ...)
2758 // No need to preserve allocated value (simpler than in ValueGraphVisitor). 2644 // No need to preserve allocated value (simpler than in ValueGraphVisitor).
2759 Value* allocated_value = BuildObjectAllocation(node); 2645 Value* allocated_value = BuildObjectAllocation(node);
2760 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); 2646 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value);
2761 BuildConstructorCall(node, push_allocated_value); 2647 BuildConstructorCall(node, push_allocated_value);
2762 } 2648 }
2763 2649
2764
2765 Value* EffectGraphVisitor::BuildInstantiator(TokenPosition token_pos) { 2650 Value* EffectGraphVisitor::BuildInstantiator(TokenPosition token_pos) {
2766 Function& outer_function = Function::Handle(Z, owner()->function().raw()); 2651 Function& outer_function = Function::Handle(Z, owner()->function().raw());
2767 while (outer_function.IsLocalFunction()) { 2652 while (outer_function.IsLocalFunction()) {
2768 outer_function = outer_function.parent_function(); 2653 outer_function = outer_function.parent_function();
2769 } 2654 }
2770 if (outer_function.IsFactory()) { 2655 if (outer_function.IsFactory()) {
2771 return NULL; 2656 return NULL;
2772 } 2657 }
2773 2658
2774 LocalVariable* instantiator = owner()->parsed_function().instantiator(); 2659 LocalVariable* instantiator = owner()->parsed_function().instantiator();
2775 ASSERT(instantiator != NULL); 2660 ASSERT(instantiator != NULL);
2776 Value* result = Bind(BuildLoadLocal(*instantiator, token_pos)); 2661 Value* result = Bind(BuildLoadLocal(*instantiator, token_pos));
2777 return result; 2662 return result;
2778 } 2663 }
2779 2664
2780
2781 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( 2665 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments(
2782 TokenPosition token_pos) { 2666 TokenPosition token_pos) {
2783 const Class& instantiator_class = 2667 const Class& instantiator_class =
2784 Class::Handle(Z, owner()->function().Owner()); 2668 Class::Handle(Z, owner()->function().Owner());
2785 if (!instantiator_class.IsGeneric()) { 2669 if (!instantiator_class.IsGeneric()) {
2786 // The type arguments are compile time constants. 2670 // The type arguments are compile time constants.
2787 TypeArguments& type_arguments = 2671 TypeArguments& type_arguments =
2788 TypeArguments::ZoneHandle(Z, TypeArguments::null()); 2672 TypeArguments::ZoneHandle(Z, TypeArguments::null());
2789 // Type is temporary. Only its type arguments are preserved. 2673 // Type is temporary. Only its type arguments are preserved.
2790 Type& type = Type::Handle(Z, Type::New(instantiator_class, type_arguments, 2674 Type& type = Type::Handle(Z, Type::New(instantiator_class, type_arguments,
(...skipping 22 matching lines...) Expand all
2813 intptr_t type_arguments_field_offset = 2697 intptr_t type_arguments_field_offset =
2814 instantiator_class.type_arguments_field_offset(); 2698 instantiator_class.type_arguments_field_offset();
2815 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); 2699 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments);
2816 2700
2817 return Bind(new (Z) LoadFieldInstr( 2701 return Bind(new (Z) LoadFieldInstr(
2818 instantiator, type_arguments_field_offset, 2702 instantiator, type_arguments_field_offset,
2819 Type::ZoneHandle(Z, Type::null()), // Not an instance, no type. 2703 Type::ZoneHandle(Z, Type::null()), // Not an instance, no type.
2820 token_pos)); 2704 token_pos));
2821 } 2705 }
2822 2706
2823
2824 Value* EffectGraphVisitor::BuildFunctionTypeArguments(TokenPosition token_pos) { 2707 Value* EffectGraphVisitor::BuildFunctionTypeArguments(TokenPosition token_pos) {
2825 LocalVariable* function_type_arguments_var = 2708 LocalVariable* function_type_arguments_var =
2826 owner()->parsed_function().function_type_arguments(); 2709 owner()->parsed_function().function_type_arguments();
2827 if (function_type_arguments_var == NULL) { 2710 if (function_type_arguments_var == NULL) {
2828 // We encountered an uninstantiated type referring to type parameters of a 2711 // We encountered an uninstantiated type referring to type parameters of a
2829 // signature that is local to the function being compiled. The type remains 2712 // signature that is local to the function being compiled. The type remains
2830 // uninstantiated. Example: Foo(f<T>(T t)) => null; 2713 // uninstantiated. Example: Foo(f<T>(T t)) => null;
2831 // Foo is non-generic, but takes a generic function f as argument. 2714 // Foo is non-generic, but takes a generic function f as argument.
2832 // The uninstantiated function type of f cannot be instantiated from within 2715 // The uninstantiated function type of f cannot be instantiated from within
2833 // Foo and should not be instantiated. It is used in uninstantiated form to 2716 // Foo and should not be instantiated. It is used in uninstantiated form to
2834 // check incoming closures for assignability. We pass an empty function 2717 // check incoming closures for assignability. We pass an empty function
2835 // type argument vector. 2718 // type argument vector.
2836 return BuildEmptyTypeArguments(token_pos); 2719 return BuildEmptyTypeArguments(token_pos);
2837 2720
2838 // Note that the function type could also get partially instantiated: 2721 // Note that the function type could also get partially instantiated:
2839 // Bar<B>(B g<T>(T t)) => null; 2722 // Bar<B>(B g<T>(T t)) => null;
2840 // In this case, function_type_arguments_var will not be null, since Bar 2723 // In this case, function_type_arguments_var will not be null, since Bar
2841 // is generic, and will be used to partially instantiate the type of g, more 2724 // is generic, and will be used to partially instantiate the type of g, more
2842 // specifically the result type of g. Note that the instantiator vector will 2725 // specifically the result type of g. Note that the instantiator vector will
2843 // have length 1, and type parameters with indices above 0, e.g. T, must 2726 // have length 1, and type parameters with indices above 0, e.g. T, must
2844 // remain uninstantiated. 2727 // remain uninstantiated.
2845 } 2728 }
2846 return Bind(BuildLoadLocal(*function_type_arguments_var, token_pos)); 2729 return Bind(BuildLoadLocal(*function_type_arguments_var, token_pos));
2847 } 2730 }
2848 2731
2849
2850 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( 2732 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments(
2851 TokenPosition token_pos, 2733 TokenPosition token_pos,
2852 const TypeArguments& type_arguments) { 2734 const TypeArguments& type_arguments) {
2853 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { 2735 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
2854 return Bind(new (Z) ConstantInstr(type_arguments)); 2736 return Bind(new (Z) ConstantInstr(type_arguments));
2855 } 2737 }
2856 // The type arguments are uninstantiated. 2738 // The type arguments are uninstantiated.
2857 const Class& instantiator_class = 2739 const Class& instantiator_class =
2858 Class::ZoneHandle(Z, owner()->function().Owner()); 2740 Class::ZoneHandle(Z, owner()->function().Owner());
2859 Value* instantiator_type_args = NULL; 2741 Value* instantiator_type_args = NULL;
(...skipping 12 matching lines...) Expand all
2872 if (type_arguments.IsInstantiated(kFunctions)) { 2754 if (type_arguments.IsInstantiated(kFunctions)) {
2873 function_type_args = BuildNullValue(token_pos); 2755 function_type_args = BuildNullValue(token_pos);
2874 } else { 2756 } else {
2875 function_type_args = BuildFunctionTypeArguments(token_pos); 2757 function_type_args = BuildFunctionTypeArguments(token_pos);
2876 } 2758 }
2877 return Bind(new (Z) InstantiateTypeArgumentsInstr( 2759 return Bind(new (Z) InstantiateTypeArgumentsInstr(
2878 token_pos, type_arguments, instantiator_class, instantiator_type_args, 2760 token_pos, type_arguments, instantiator_class, instantiator_type_args,
2879 function_type_args, owner()->GetNextDeoptId())); 2761 function_type_args, owner()->GetNextDeoptId()));
2880 } 2762 }
2881 2763
2882
2883 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) { 2764 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
2884 if (node->constructor().IsFactory()) { 2765 if (node->constructor().IsFactory()) {
2885 EffectGraphVisitor::VisitConstructorCallNode(node); 2766 EffectGraphVisitor::VisitConstructorCallNode(node);
2886 return; 2767 return;
2887 } 2768 }
2888 2769
2889 // t_n contains the allocated and initialized object. 2770 // t_n contains the allocated and initialized object.
2890 // t_n <- AllocateObject(class) 2771 // t_n <- AllocateObject(class)
2891 // t_n <- StoreLocal(temp, t_n); 2772 // t_n <- StoreLocal(temp, t_n);
2892 // t_n+1 <- ctor-arg 2773 // t_n+1 <- ctor-arg
2893 // t_n+2... <- constructor arguments start here 2774 // t_n+2... <- constructor arguments start here
2894 // StaticCall(constructor, t_n, t_n+1, ...) 2775 // StaticCall(constructor, t_n, t_n+1, ...)
2895 // tn <- LoadLocal(temp) 2776 // tn <- LoadLocal(temp)
2896 2777
2897 Value* allocate = BuildObjectAllocation(node); 2778 Value* allocate = BuildObjectAllocation(node);
2898 { 2779 {
2899 LocalVariable* tmp_var = EnterTempLocalScope(allocate); 2780 LocalVariable* tmp_var = EnterTempLocalScope(allocate);
2900 Value* allocated_tmp = 2781 Value* allocated_tmp =
2901 Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos())); 2782 Bind(new (Z) LoadLocalInstr(*tmp_var, node->token_pos()));
2902 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); 2783 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp);
2903 BuildConstructorCall(node, push_allocated_value); 2784 BuildConstructorCall(node, push_allocated_value);
2904 ReturnDefinition(ExitTempLocalScope(allocate)); 2785 ReturnDefinition(ExitTempLocalScope(allocate));
2905 } 2786 }
2906 } 2787 }
2907 2788
2908
2909 void EffectGraphVisitor::BuildInstanceGetterConditional( 2789 void EffectGraphVisitor::BuildInstanceGetterConditional(
2910 InstanceGetterNode* node) { 2790 InstanceGetterNode* node) {
2911 const TokenPosition token_pos = node->token_pos(); 2791 const TokenPosition token_pos = node->token_pos();
2912 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); 2792 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
2913 LoadLocalNode* load_temp = new (Z) LoadLocalNode(token_pos, temp_var); 2793 LoadLocalNode* load_temp = new (Z) LoadLocalNode(token_pos, temp_var);
2914 2794
2915 LiteralNode* null_constant = 2795 LiteralNode* null_constant =
2916 new (Z) LiteralNode(ST(token_pos), Object::null_instance()); 2796 new (Z) LiteralNode(ST(token_pos), Object::null_instance());
2917 ComparisonNode* check_is_null = new (Z) 2797 ComparisonNode* check_is_null = new (Z)
2918 ComparisonNode(ST(token_pos), Token::kEQ, load_temp, null_constant); 2798 ComparisonNode(ST(token_pos), Token::kEQ, load_temp, null_constant);
2919 TestGraphVisitor for_test(owner(), ST(token_pos)); 2799 TestGraphVisitor for_test(owner(), ST(token_pos));
2920 check_is_null->Visit(&for_test); 2800 check_is_null->Visit(&for_test);
2921 2801
2922 EffectGraphVisitor for_true(owner()); 2802 EffectGraphVisitor for_true(owner());
2923 EffectGraphVisitor for_false(owner()); 2803 EffectGraphVisitor for_false(owner());
2924 2804
2925 StoreLocalNode* store_null = 2805 StoreLocalNode* store_null =
2926 new (Z) StoreLocalNode(ST(token_pos), temp_var, null_constant); 2806 new (Z) StoreLocalNode(ST(token_pos), temp_var, null_constant);
2927 store_null->Visit(&for_true); 2807 store_null->Visit(&for_true);
2928 2808
2929 InstanceGetterNode* getter = 2809 InstanceGetterNode* getter =
2930 new (Z) InstanceGetterNode(token_pos, load_temp, node->field_name()); 2810 new (Z) InstanceGetterNode(token_pos, load_temp, node->field_name());
2931 StoreLocalNode* store_getter = 2811 StoreLocalNode* store_getter =
2932 new (Z) StoreLocalNode(ST(token_pos), temp_var, getter); 2812 new (Z) StoreLocalNode(ST(token_pos), temp_var, getter);
2933 store_getter->Visit(&for_false); 2813 store_getter->Visit(&for_false);
2934 2814
2935 Join(for_test, for_true, for_false); 2815 Join(for_test, for_true, for_false);
2936 } 2816 }
2937 2817
2938
2939 void ValueGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { 2818 void ValueGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
2940 if (node->is_conditional()) { 2819 if (node->is_conditional()) {
2941 ValueGraphVisitor for_receiver(owner()); 2820 ValueGraphVisitor for_receiver(owner());
2942 node->receiver()->Visit(&for_receiver); 2821 node->receiver()->Visit(&for_receiver);
2943 Append(for_receiver); 2822 Append(for_receiver);
2944 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos())); 2823 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos()));
2945 BuildInstanceGetterConditional(node); 2824 BuildInstanceGetterConditional(node);
2946 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); 2825 ReturnDefinition(BuildLoadExprTemp(node->token_pos()));
2947 } else { 2826 } else {
2948 EffectGraphVisitor::VisitInstanceGetterNode(node); 2827 EffectGraphVisitor::VisitInstanceGetterNode(node);
2949 } 2828 }
2950 } 2829 }
2951 2830
2952
2953 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { 2831 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
2954 ValueGraphVisitor for_receiver(owner()); 2832 ValueGraphVisitor for_receiver(owner());
2955 node->receiver()->Visit(&for_receiver); 2833 node->receiver()->Visit(&for_receiver);
2956 Append(for_receiver); 2834 Append(for_receiver);
2957 if (node->is_conditional()) { 2835 if (node->is_conditional()) {
2958 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos())); 2836 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos()));
2959 BuildInstanceGetterConditional(node); 2837 BuildInstanceGetterConditional(node);
2960 } else { 2838 } else {
2961 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); 2839 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
2962 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2840 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2963 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1); 2841 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1);
2964 arguments->Add(push_receiver); 2842 arguments->Add(push_receiver);
2965 const String& name = 2843 const String& name =
2966 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name())); 2844 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name()));
2967 const intptr_t kTypeArgsLen = 0; 2845 const intptr_t kTypeArgsLen = 0;
2968 InstanceCallInstr* call = new (Z) 2846 InstanceCallInstr* call = new (Z)
2969 InstanceCallInstr(node->token_pos(), name, Token::kGET, arguments, 2847 InstanceCallInstr(node->token_pos(), name, Token::kGET, arguments,
2970 kTypeArgsLen, Object::null_array(), 1, 2848 kTypeArgsLen, Object::null_array(), 1,
2971 owner()->ic_data_array(), owner()->GetNextDeoptId()); 2849 owner()->ic_data_array(), owner()->GetNextDeoptId());
2972 ReturnDefinition(call); 2850 ReturnDefinition(call);
2973 } 2851 }
2974 } 2852 }
2975 2853
2976
2977 void EffectGraphVisitor::BuildInstanceSetterArguments( 2854 void EffectGraphVisitor::BuildInstanceSetterArguments(
2978 InstanceSetterNode* node, 2855 InstanceSetterNode* node,
2979 ZoneGrowableArray<PushArgumentInstr*>* arguments, 2856 ZoneGrowableArray<PushArgumentInstr*>* arguments,
2980 bool result_is_needed) { 2857 bool result_is_needed) {
2981 ValueGraphVisitor for_receiver(owner()); 2858 ValueGraphVisitor for_receiver(owner());
2982 node->receiver()->Visit(&for_receiver); 2859 node->receiver()->Visit(&for_receiver);
2983 Append(for_receiver); 2860 Append(for_receiver);
2984 arguments->Add(PushArgument(for_receiver.value())); 2861 arguments->Add(PushArgument(for_receiver.value()));
2985 2862
2986 ValueGraphVisitor for_value(owner()); 2863 ValueGraphVisitor for_value(owner());
2987 node->value()->Visit(&for_value); 2864 node->value()->Visit(&for_value);
2988 Append(for_value); 2865 Append(for_value);
2989 2866
2990 Value* value = NULL; 2867 Value* value = NULL;
2991 if (result_is_needed) { 2868 if (result_is_needed) {
2992 value = Bind(BuildStoreExprTemp(for_value.value(), node->token_pos())); 2869 value = Bind(BuildStoreExprTemp(for_value.value(), node->token_pos()));
2993 } else { 2870 } else {
2994 value = for_value.value(); 2871 value = for_value.value();
2995 } 2872 }
2996 arguments->Add(PushArgument(value)); 2873 arguments->Add(PushArgument(value));
2997 } 2874 }
2998 2875
2999
3000 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 2876 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
3001 const TokenPosition token_pos = node->token_pos(); 2877 const TokenPosition token_pos = node->token_pos();
3002 if (node->is_conditional()) { 2878 if (node->is_conditional()) {
3003 ValueGraphVisitor for_receiver(owner()); 2879 ValueGraphVisitor for_receiver(owner());
3004 node->receiver()->Visit(&for_receiver); 2880 node->receiver()->Visit(&for_receiver);
3005 Append(for_receiver); 2881 Append(for_receiver);
3006 Do(BuildStoreExprTemp(for_receiver.value(), token_pos)); 2882 Do(BuildStoreExprTemp(for_receiver.value(), token_pos));
3007 2883
3008 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); 2884 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
3009 LoadLocalNode* load_temp = new (Z) LoadLocalNode(ST(token_pos), temp_var); 2885 LoadLocalNode* load_temp = new (Z) LoadLocalNode(ST(token_pos), temp_var);
(...skipping 20 matching lines...) Expand all
3030 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); 2906 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
3031 const int kTypeArgsLen = 0; 2907 const int kTypeArgsLen = 0;
3032 const intptr_t kNumArgsChecked = 1; // Do not check value type. 2908 const intptr_t kNumArgsChecked = 1; // Do not check value type.
3033 InstanceCallInstr* call = new (Z) 2909 InstanceCallInstr* call = new (Z)
3034 InstanceCallInstr(token_pos, name, Token::kSET, arguments, kTypeArgsLen, 2910 InstanceCallInstr(token_pos, name, Token::kSET, arguments, kTypeArgsLen,
3035 Object::null_array(), kNumArgsChecked, 2911 Object::null_array(), kNumArgsChecked,
3036 owner()->ic_data_array(), owner()->GetNextDeoptId()); 2912 owner()->ic_data_array(), owner()->GetNextDeoptId());
3037 ReturnDefinition(call); 2913 ReturnDefinition(call);
3038 } 2914 }
3039 2915
3040
3041 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 2916 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
3042 const TokenPosition token_pos = node->token_pos(); 2917 const TokenPosition token_pos = node->token_pos();
3043 if (node->is_conditional()) { 2918 if (node->is_conditional()) {
3044 ValueGraphVisitor for_receiver(owner()); 2919 ValueGraphVisitor for_receiver(owner());
3045 node->receiver()->Visit(&for_receiver); 2920 node->receiver()->Visit(&for_receiver);
3046 Append(for_receiver); 2921 Append(for_receiver);
3047 Do(BuildStoreExprTemp(for_receiver.value(), token_pos)); 2922 Do(BuildStoreExprTemp(for_receiver.value(), token_pos));
3048 2923
3049 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); 2924 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
3050 LoadLocalNode* load_temp = new (Z) LoadLocalNode(ST(token_pos), temp_var); 2925 LoadLocalNode* load_temp = new (Z) LoadLocalNode(ST(token_pos), temp_var);
(...skipping 25 matching lines...) Expand all
3076 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); 2951 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
3077 const intptr_t kTypeArgsLen = 0; 2952 const intptr_t kTypeArgsLen = 0;
3078 const intptr_t kNumArgsChecked = 1; // Do not check value type. 2953 const intptr_t kNumArgsChecked = 1; // Do not check value type.
3079 Do(new (Z) InstanceCallInstr(token_pos, name, Token::kSET, arguments, 2954 Do(new (Z) InstanceCallInstr(token_pos, name, Token::kSET, arguments,
3080 kTypeArgsLen, Object::null_array(), 2955 kTypeArgsLen, Object::null_array(),
3081 kNumArgsChecked, owner()->ic_data_array(), 2956 kNumArgsChecked, owner()->ic_data_array(),
3082 owner()->GetNextDeoptId())); 2957 owner()->GetNextDeoptId()));
3083 ReturnDefinition(BuildLoadExprTemp(token_pos)); 2958 ReturnDefinition(BuildLoadExprTemp(token_pos));
3084 } 2959 }
3085 2960
3086
3087 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { 2961 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
3088 const String& getter_name = 2962 const String& getter_name =
3089 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name())); 2963 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name()));
3090 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2964 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3091 new (Z) ZoneGrowableArray<PushArgumentInstr*>(); 2965 new (Z) ZoneGrowableArray<PushArgumentInstr*>();
3092 Function& getter_function = Function::ZoneHandle(Z, Function::null()); 2966 Function& getter_function = Function::ZoneHandle(Z, Function::null());
3093 if (node->is_super_getter()) { 2967 if (node->is_super_getter()) {
3094 // Statically resolved instance getter, i.e. "super getter". 2968 // Statically resolved instance getter, i.e. "super getter".
3095 ASSERT(node->receiver() != NULL); 2969 ASSERT(node->receiver() != NULL);
3096 getter_function = 2970 getter_function =
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3142 } 3016 }
3143 ASSERT(!getter_function.IsNull()); 3017 ASSERT(!getter_function.IsNull());
3144 const intptr_t kTypeArgsLen = 0; 3018 const intptr_t kTypeArgsLen = 0;
3145 StaticCallInstr* call = new (Z) StaticCallInstr( 3019 StaticCallInstr* call = new (Z) StaticCallInstr(
3146 node->token_pos(), getter_function, kTypeArgsLen, 3020 node->token_pos(), getter_function, kTypeArgsLen,
3147 Object::null_array(), // No names 3021 Object::null_array(), // No names
3148 arguments, owner()->ic_data_array(), owner()->GetNextDeoptId()); 3022 arguments, owner()->ic_data_array(), owner()->GetNextDeoptId());
3149 ReturnDefinition(call); 3023 ReturnDefinition(call);
3150 } 3024 }
3151 3025
3152
3153 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, 3026 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node,
3154 bool result_is_needed) { 3027 bool result_is_needed) {
3155 const String& setter_name = 3028 const String& setter_name =
3156 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); 3029 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
3157 ZoneGrowableArray<PushArgumentInstr*>* arguments = 3030 ZoneGrowableArray<PushArgumentInstr*>* arguments =
3158 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1); 3031 new (Z) ZoneGrowableArray<PushArgumentInstr*>(1);
3159 const TokenPosition token_pos = node->token_pos(); 3032 const TokenPosition token_pos = node->token_pos();
3160 // A super setter is an instance setter whose setter function is 3033 // A super setter is an instance setter whose setter function is
3161 // resolved at compile time (in the caller instance getter's super class). 3034 // resolved at compile time (in the caller instance getter's super class).
3162 // Unlike a static getter, a super getter has a receiver parameter. 3035 // Unlike a static getter, a super getter has a receiver parameter.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3211 owner()->GetNextDeoptId()); 3084 owner()->GetNextDeoptId());
3212 } 3085 }
3213 if (result_is_needed) { 3086 if (result_is_needed) {
3214 Do(call); 3087 Do(call);
3215 ReturnDefinition(BuildLoadExprTemp(token_pos)); 3088 ReturnDefinition(BuildLoadExprTemp(token_pos));
3216 } else { 3089 } else {
3217 ReturnDefinition(call); 3090 ReturnDefinition(call);
3218 } 3091 }
3219 } 3092 }
3220 3093
3221
3222 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { 3094 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) {
3223 BuildStaticSetter(node, false); // Result not needed. 3095 BuildStaticSetter(node, false); // Result not needed.
3224 } 3096 }
3225 3097
3226
3227 void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { 3098 void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) {
3228 BuildStaticSetter(node, true); // Result needed. 3099 BuildStaticSetter(node, true); // Result needed.
3229 } 3100 }
3230 3101
3231
3232 static intptr_t OffsetForLengthGetter(MethodRecognizer::Kind kind) { 3102 static intptr_t OffsetForLengthGetter(MethodRecognizer::Kind kind) {
3233 switch (kind) { 3103 switch (kind) {
3234 case MethodRecognizer::kObjectArrayLength: 3104 case MethodRecognizer::kObjectArrayLength:
3235 case MethodRecognizer::kImmutableArrayLength: 3105 case MethodRecognizer::kImmutableArrayLength:
3236 return Array::length_offset(); 3106 return Array::length_offset();
3237 case MethodRecognizer::kTypedDataLength: 3107 case MethodRecognizer::kTypedDataLength:
3238 // .length is defined in _TypedList which is the base class for internal 3108 // .length is defined in _TypedList which is the base class for internal
3239 // and external typed data. 3109 // and external typed data.
3240 ASSERT(TypedData::length_offset() == ExternalTypedData::length_offset()); 3110 ASSERT(TypedData::length_offset() == ExternalTypedData::length_offset());
3241 return TypedData::length_offset(); 3111 return TypedData::length_offset();
3242 case MethodRecognizer::kGrowableArrayLength: 3112 case MethodRecognizer::kGrowableArrayLength:
3243 return GrowableObjectArray::length_offset(); 3113 return GrowableObjectArray::length_offset();
3244 default: 3114 default:
3245 UNREACHABLE(); 3115 UNREACHABLE();
3246 return 0; 3116 return 0;
3247 } 3117 }
3248 } 3118 }
3249 3119
3250
3251 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(LocalScope* scope, 3120 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(LocalScope* scope,
3252 TokenPosition token_pos) { 3121 TokenPosition token_pos) {
3253 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(), 3122 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(),
3254 true); // Test only. 3123 true); // Test only.
3255 return new (Z) LoadLocalInstr(*receiver_var, token_pos); 3124 return new (Z) LoadLocalInstr(*receiver_var, token_pos);
3256 } 3125 }
3257 3126
3258
3259 LoadFieldInstr* EffectGraphVisitor::BuildNativeGetter( 3127 LoadFieldInstr* EffectGraphVisitor::BuildNativeGetter(
3260 NativeBodyNode* node, 3128 NativeBodyNode* node,
3261 MethodRecognizer::Kind kind, 3129 MethodRecognizer::Kind kind,
3262 intptr_t offset, 3130 intptr_t offset,
3263 const Type& type, 3131 const Type& type,
3264 intptr_t class_id) { 3132 intptr_t class_id) {
3265 Value* receiver = Bind(BuildLoadThisVar(node->scope(), node->token_pos())); 3133 Value* receiver = Bind(BuildLoadThisVar(node->scope(), node->token_pos()));
3266 LoadFieldInstr* load = 3134 LoadFieldInstr* load =
3267 new (Z) LoadFieldInstr(receiver, offset, type, node->token_pos()); 3135 new (Z) LoadFieldInstr(receiver, offset, type, node->token_pos());
3268 load->set_result_cid(class_id); 3136 load->set_result_cid(class_id);
3269 load->set_recognized_kind(kind); 3137 load->set_recognized_kind(kind);
3270 return load; 3138 return load;
3271 } 3139 }
3272 3140
3273
3274 ConstantInstr* EffectGraphVisitor::DoNativeSetterStoreValue( 3141 ConstantInstr* EffectGraphVisitor::DoNativeSetterStoreValue(
3275 NativeBodyNode* node, 3142 NativeBodyNode* node,
3276 intptr_t offset, 3143 intptr_t offset,
3277 StoreBarrierType emit_store_barrier) { 3144 StoreBarrierType emit_store_barrier) {
3278 Value* receiver = Bind(BuildLoadThisVar(node->scope(), node->token_pos())); 3145 Value* receiver = Bind(BuildLoadThisVar(node->scope(), node->token_pos()));
3279 LocalVariable* value_var = 3146 LocalVariable* value_var =
3280 node->scope()->LookupVariable(Symbols::Value(), true); 3147 node->scope()->LookupVariable(Symbols::Value(), true);
3281 Value* value = Bind(new (Z) LoadLocalInstr(*value_var, node->token_pos())); 3148 Value* value = Bind(new (Z) LoadLocalInstr(*value_var, node->token_pos()));
3282 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr( 3149 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr(
3283 offset, receiver, value, emit_store_barrier, node->token_pos()); 3150 offset, receiver, value, emit_store_barrier, node->token_pos());
3284 Do(store); 3151 Do(store);
3285 return new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null())); 3152 return new (Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()));
3286 } 3153 }
3287 3154
3288
3289 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { 3155 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
3290 const Function& function = owner()->function(); 3156 const Function& function = owner()->function();
3291 const TokenPosition token_pos = node->token_pos(); 3157 const TokenPosition token_pos = node->token_pos();
3292 if (!function.IsClosureFunction()) { 3158 if (!function.IsClosureFunction()) {
3293 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); 3159 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
3294 switch (kind) { 3160 switch (kind) {
3295 case MethodRecognizer::kObjectEquals: { 3161 case MethodRecognizer::kObjectEquals: {
3296 Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos)); 3162 Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos));
3297 LocalVariable* other_var = 3163 LocalVariable* other_var =
3298 node->scope()->LookupVariable(Symbols::Other(), 3164 node->scope()->LookupVariable(Symbols::Other(),
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
3436 } 3302 }
3437 default: 3303 default:
3438 break; 3304 break;
3439 } 3305 }
3440 } 3306 }
3441 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); 3307 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode");
3442 NativeCallInstr* native_call = new (Z) NativeCallInstr(node); 3308 NativeCallInstr* native_call = new (Z) NativeCallInstr(node);
3443 ReturnDefinition(native_call); 3309 ReturnDefinition(native_call);
3444 } 3310 }
3445 3311
3446
3447 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) { 3312 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) {
3448 // PrimaryNodes are temporary during parsing. 3313 // PrimaryNodes are temporary during parsing.
3449 UNREACHABLE(); 3314 UNREACHABLE();
3450 } 3315 }
3451 3316
3452
3453 // <Expression> ::= LoadLocal { local: LocalVariable } 3317 // <Expression> ::= LoadLocal { local: LocalVariable }
3454 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { 3318 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
3455 // Nothing to do. 3319 // Nothing to do.
3456 } 3320 }
3457 3321
3458
3459 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { 3322 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
3460 Definition* load = BuildLoadLocal(node->local(), node->token_pos()); 3323 Definition* load = BuildLoadLocal(node->local(), node->token_pos());
3461 ReturnDefinition(load); 3324 ReturnDefinition(load);
3462 } 3325 }
3463 3326
3464
3465 // <Expression> ::= StoreLocal { local: LocalVariable 3327 // <Expression> ::= StoreLocal { local: LocalVariable
3466 // value: <Expression> } 3328 // value: <Expression> }
3467 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { 3329 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
3468 // If the right hand side is an expression that does not contain 3330 // If the right hand side is an expression that does not contain
3469 // a safe point for the debugger to stop, add an explicit stub 3331 // a safe point for the debugger to stop, add an explicit stub
3470 // call. Exception: don't do this when assigning to or from internal 3332 // call. Exception: don't do this when assigning to or from internal
3471 // variables, or for generated code that has no source position. 3333 // variables, or for generated code that has no source position.
3472 if (FLAG_support_debugger) { 3334 if (FLAG_support_debugger) {
3473 AstNode* rhs = node->value(); 3335 AstNode* rhs = node->value();
3474 if (rhs->IsAssignableNode()) { 3336 if (rhs->IsAssignableNode()) {
(...skipping 17 matching lines...) Expand all
3492 if (Isolate::Current()->type_checks()) { 3354 if (Isolate::Current()->type_checks()) {
3493 store_value = 3355 store_value =
3494 BuildAssignableValue(node->value()->token_pos(), store_value, 3356 BuildAssignableValue(node->value()->token_pos(), store_value,
3495 node->local().type(), node->local().name()); 3357 node->local().type(), node->local().name());
3496 } 3358 }
3497 Definition* store = 3359 Definition* store =
3498 BuildStoreLocal(node->local(), store_value, node->token_pos()); 3360 BuildStoreLocal(node->local(), store_value, node->token_pos());
3499 ReturnDefinition(store); 3361 ReturnDefinition(store);
3500 } 3362 }
3501 3363
3502
3503 void EffectGraphVisitor::VisitLoadInstanceFieldNode( 3364 void EffectGraphVisitor::VisitLoadInstanceFieldNode(
3504 LoadInstanceFieldNode* node) { 3365 LoadInstanceFieldNode* node) {
3505 ValueGraphVisitor for_instance(owner()); 3366 ValueGraphVisitor for_instance(owner());
3506 node->instance()->Visit(&for_instance); 3367 node->instance()->Visit(&for_instance);
3507 Append(for_instance); 3368 Append(for_instance);
3508 LoadFieldInstr* load = 3369 LoadFieldInstr* load =
3509 new (Z) LoadFieldInstr(for_instance.value(), &node->field(), 3370 new (Z) LoadFieldInstr(for_instance.value(), &node->field(),
3510 AbstractType::ZoneHandle(Z, node->field().type()), 3371 AbstractType::ZoneHandle(Z, node->field().type()),
3511 node->token_pos(), &owner()->parsed_function()); 3372 node->token_pos(), &owner()->parsed_function());
3512 ReturnDefinition(load); 3373 ReturnDefinition(load);
3513 } 3374 }
3514 3375
3515
3516 void EffectGraphVisitor::VisitStoreInstanceFieldNode( 3376 void EffectGraphVisitor::VisitStoreInstanceFieldNode(
3517 StoreInstanceFieldNode* node) { 3377 StoreInstanceFieldNode* node) {
3518 const TokenPosition token_pos = node->token_pos(); 3378 const TokenPosition token_pos = node->token_pos();
3519 ValueGraphVisitor for_instance(owner()); 3379 ValueGraphVisitor for_instance(owner());
3520 node->instance()->Visit(&for_instance); 3380 node->instance()->Visit(&for_instance);
3521 Append(for_instance); 3381 Append(for_instance);
3522 ValueGraphVisitor for_value(owner()); 3382 ValueGraphVisitor for_value(owner());
3523 node->value()->Visit(&for_value); 3383 node->value()->Visit(&for_value);
3524 Append(for_value); 3384 Append(for_value);
3525 Value* store_value = for_value.value(); 3385 Value* store_value = for_value.value();
(...skipping 17 matching lines...) Expand all
3543 store_value = Bind(BuildLoadExprTemp(token_pos)); 3403 store_value = Bind(BuildLoadExprTemp(token_pos));
3544 } 3404 }
3545 StoreInstanceFieldInstr* store = new (Z) 3405 StoreInstanceFieldInstr* store = new (Z)
3546 StoreInstanceFieldInstr(node->field(), for_instance.value(), store_value, 3406 StoreInstanceFieldInstr(node->field(), for_instance.value(), store_value,
3547 kEmitStoreBarrier, token_pos); 3407 kEmitStoreBarrier, token_pos);
3548 // Maybe initializing unboxed store. 3408 // Maybe initializing unboxed store.
3549 store->set_is_initialization(node->is_initializer()); 3409 store->set_is_initialization(node->is_initializer());
3550 ReturnDefinition(store); 3410 ReturnDefinition(store);
3551 } 3411 }
3552 3412
3553
3554 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { 3413 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
3555 const TokenPosition token_pos = node->token_pos(); 3414 const TokenPosition token_pos = node->token_pos();
3556 if (node->field().is_const()) { 3415 if (node->field().is_const()) {
3557 ASSERT(node->field().StaticValue() != Object::sentinel().raw()); 3416 ASSERT(node->field().StaticValue() != Object::sentinel().raw());
3558 ASSERT(node->field().StaticValue() != Object::transition_sentinel().raw()); 3417 ASSERT(node->field().StaticValue() != Object::transition_sentinel().raw());
3559 Definition* result = new (Z) ConstantInstr( 3418 Definition* result = new (Z) ConstantInstr(
3560 Instance::ZoneHandle(Z, node->field().StaticValue()), token_pos); 3419 Instance::ZoneHandle(Z, node->field().StaticValue()), token_pos);
3561 return ReturnDefinition(result); 3420 return ReturnDefinition(result);
3562 } 3421 }
3563 Value* field_value = Bind(new (Z) ConstantInstr( 3422 Value* field_value = Bind(new (Z) ConstantInstr(
3564 Field::ZoneHandle(Z, node->field().Original()), token_pos)); 3423 Field::ZoneHandle(Z, node->field().Original()), token_pos));
3565 LoadStaticFieldInstr* load = 3424 LoadStaticFieldInstr* load =
3566 new (Z) LoadStaticFieldInstr(field_value, token_pos); 3425 new (Z) LoadStaticFieldInstr(field_value, token_pos);
3567 ReturnDefinition(load); 3426 ReturnDefinition(load);
3568 } 3427 }
3569 3428
3570
3571 Definition* EffectGraphVisitor::BuildStoreStaticField( 3429 Definition* EffectGraphVisitor::BuildStoreStaticField(
3572 StoreStaticFieldNode* node, 3430 StoreStaticFieldNode* node,
3573 bool result_is_needed, 3431 bool result_is_needed,
3574 TokenPosition token_pos) { 3432 TokenPosition token_pos) {
3575 if (FLAG_support_debugger) { 3433 if (FLAG_support_debugger) {
3576 // If the right hand side is an expression that does not contain 3434 // If the right hand side is an expression that does not contain
3577 // a safe point for the debugger to stop, add an explicit stub 3435 // a safe point for the debugger to stop, add an explicit stub
3578 // call. 3436 // call.
3579 AstNode* rhs = node->value(); 3437 AstNode* rhs = node->value();
3580 if (rhs->IsAssignableNode()) { 3438 if (rhs->IsAssignableNode()) {
(...skipping 21 matching lines...) Expand all
3602 new (Z) StoreStaticFieldInstr(node->field(), store_value, token_pos); 3460 new (Z) StoreStaticFieldInstr(node->field(), store_value, token_pos);
3603 3461
3604 if (result_is_needed) { 3462 if (result_is_needed) {
3605 Do(store); 3463 Do(store);
3606 return BuildLoadExprTemp(token_pos); 3464 return BuildLoadExprTemp(token_pos);
3607 } else { 3465 } else {
3608 return store; 3466 return store;
3609 } 3467 }
3610 } 3468 }
3611 3469
3612
3613 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { 3470 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
3614 ReturnDefinition( 3471 ReturnDefinition(
3615 BuildStoreStaticField(node, kResultNotNeeded, node->token_pos())); 3472 BuildStoreStaticField(node, kResultNotNeeded, node->token_pos()));
3616 } 3473 }
3617 3474
3618
3619 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { 3475 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
3620 ReturnDefinition( 3476 ReturnDefinition(
3621 BuildStoreStaticField(node, kResultNeeded, node->token_pos())); 3477 BuildStoreStaticField(node, kResultNeeded, node->token_pos()));
3622 } 3478 }
3623 3479
3624
3625 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { 3480 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
3626 Function* super_function = NULL; 3481 Function* super_function = NULL;
3627 if (node->IsSuperLoad()) { 3482 if (node->IsSuperLoad()) {
3628 // Resolve the load indexed operator in the super class. 3483 // Resolve the load indexed operator in the super class.
3629 super_function = &Function::ZoneHandle( 3484 super_function = &Function::ZoneHandle(
3630 Z, Resolver::ResolveDynamicAnyArgs(Z, node->super_class(), 3485 Z, Resolver::ResolveDynamicAnyArgs(Z, node->super_class(),
3631 Symbols::IndexToken())); 3486 Symbols::IndexToken()));
3632 if (super_function->IsNull()) { 3487 if (super_function->IsNull()) {
3633 // Could not resolve super operator. Generate call noSuchMethod() of the 3488 // Could not resolve super operator. Generate call noSuchMethod() of the
3634 // super class instead. 3489 // super class instead.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3666 // Generate dynamic call to index operator. 3521 // Generate dynamic call to index operator.
3667 const intptr_t checked_argument_count = 1; 3522 const intptr_t checked_argument_count = 1;
3668 InstanceCallInstr* load = new (Z) InstanceCallInstr( 3523 InstanceCallInstr* load = new (Z) InstanceCallInstr(
3669 node->token_pos(), Symbols::IndexToken(), Token::kINDEX, arguments, 3524 node->token_pos(), Symbols::IndexToken(), Token::kINDEX, arguments,
3670 kTypeArgsLen, Object::null_array(), checked_argument_count, 3525 kTypeArgsLen, Object::null_array(), checked_argument_count,
3671 owner()->ic_data_array(), owner()->GetNextDeoptId()); 3526 owner()->ic_data_array(), owner()->GetNextDeoptId());
3672 ReturnDefinition(load); 3527 ReturnDefinition(load);
3673 } 3528 }
3674 } 3529 }
3675 3530
3676
3677 Definition* EffectGraphVisitor::BuildStoreIndexedValues(StoreIndexedNode* node, 3531 Definition* EffectGraphVisitor::BuildStoreIndexedValues(StoreIndexedNode* node,
3678 bool result_is_needed) { 3532 bool result_is_needed) {
3679 Function* super_function = NULL; 3533 Function* super_function = NULL;
3680 const TokenPosition token_pos = node->token_pos(); 3534 const TokenPosition token_pos = node->token_pos();
3681 if (node->IsSuperStore()) { 3535 if (node->IsSuperStore()) {
3682 // Resolve the store indexed operator in the super class. 3536 // Resolve the store indexed operator in the super class.
3683 super_function = &Function::ZoneHandle( 3537 super_function = &Function::ZoneHandle(
3684 Z, Resolver::ResolveDynamicAnyArgs(Z, node->super_class(), 3538 Z, Resolver::ResolveDynamicAnyArgs(Z, node->super_class(),
3685 Symbols::AssignIndexToken())); 3539 Symbols::AssignIndexToken()));
3686 if (super_function->IsNull()) { 3540 if (super_function->IsNull()) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
3750 owner()->ic_data_array(), owner()->GetNextDeoptId()); 3604 owner()->ic_data_array(), owner()->GetNextDeoptId());
3751 if (result_is_needed) { 3605 if (result_is_needed) {
3752 Do(store); 3606 Do(store);
3753 return BuildLoadExprTemp(token_pos); 3607 return BuildLoadExprTemp(token_pos);
3754 } else { 3608 } else {
3755 return store; 3609 return store;
3756 } 3610 }
3757 } 3611 }
3758 } 3612 }
3759 3613
3760
3761 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { 3614 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
3762 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded)); 3615 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded));
3763 } 3616 }
3764 3617
3765
3766 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { 3618 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
3767 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded)); 3619 ReturnDefinition(BuildStoreIndexedValues(node, kResultNeeded));
3768 } 3620 }
3769 3621
3770
3771 bool EffectGraphVisitor::HasContextScope() const { 3622 bool EffectGraphVisitor::HasContextScope() const {
3772 const ContextScope& context_scope = 3623 const ContextScope& context_scope =
3773 ContextScope::Handle(owner()->function().context_scope()); 3624 ContextScope::Handle(owner()->function().context_scope());
3774 return !context_scope.IsNull() && (context_scope.num_variables() > 0); 3625 return !context_scope.IsNull() && (context_scope.num_variables() > 0);
3775 } 3626 }
3776 3627
3777
3778 void EffectGraphVisitor::UnchainContexts(intptr_t n) { 3628 void EffectGraphVisitor::UnchainContexts(intptr_t n) {
3779 // TODO(johnmccutchan): Pass this in. 3629 // TODO(johnmccutchan): Pass this in.
3780 const TokenPosition token_pos = TokenPosition::kContext; 3630 const TokenPosition token_pos = TokenPosition::kContext;
3781 if (n > 0) { 3631 if (n > 0) {
3782 Value* context = Bind(BuildCurrentContext(token_pos)); 3632 Value* context = Bind(BuildCurrentContext(token_pos));
3783 while (n-- > 0) { 3633 while (n-- > 0) {
3784 context = Bind(new (Z) LoadFieldInstr(context, Context::parent_offset(), 3634 context = Bind(new (Z) LoadFieldInstr(context, Context::parent_offset(),
3785 // Not an instance, no type. 3635 // Not an instance, no type.
3786 Type::ZoneHandle(Z, Type::null()), 3636 Type::ZoneHandle(Z, Type::null()),
3787 token_pos)); 3637 token_pos));
3788 } 3638 }
3789 Do(BuildStoreContext(context, token_pos)); 3639 Do(BuildStoreContext(context, token_pos));
3790 } 3640 }
3791 } 3641 }
3792 3642
3793
3794 void EffectGraphVisitor::AdjustContextLevel(LocalScope* target_scope) { 3643 void EffectGraphVisitor::AdjustContextLevel(LocalScope* target_scope) {
3795 ASSERT(target_scope != NULL); 3644 ASSERT(target_scope != NULL);
3796 intptr_t target_context_level = 0; 3645 intptr_t target_context_level = 0;
3797 if (target_scope->num_context_variables() > 0) { 3646 if (target_scope->num_context_variables() > 0) {
3798 // The scope of the target label allocates a context, therefore its outer 3647 // The scope of the target label allocates a context, therefore its outer
3799 // scope is at a lower context level. 3648 // scope is at a lower context level.
3800 target_context_level = target_scope->context_level() - 1; 3649 target_context_level = target_scope->context_level() - 1;
3801 } else { 3650 } else {
3802 // The scope of the target label does not allocate a context, so its outer 3651 // The scope of the target label does not allocate a context, so its outer
3803 // scope is at the same context level. Find it. 3652 // scope is at the same context level. Find it.
3804 while ((target_scope != NULL) && 3653 while ((target_scope != NULL) &&
3805 (target_scope->num_context_variables() == 0)) { 3654 (target_scope->num_context_variables() == 0)) {
3806 target_scope = target_scope->parent(); 3655 target_scope = target_scope->parent();
3807 } 3656 }
3808 if (target_scope != NULL) { 3657 if (target_scope != NULL) {
3809 target_context_level = target_scope->context_level(); 3658 target_context_level = target_scope->context_level();
3810 } 3659 }
3811 } 3660 }
3812 ASSERT(target_context_level >= 0); 3661 ASSERT(target_context_level >= 0);
3813 intptr_t current_context_level = owner()->context_level(); 3662 intptr_t current_context_level = owner()->context_level();
3814 ASSERT(current_context_level >= target_context_level); 3663 ASSERT(current_context_level >= target_context_level);
3815 UnchainContexts(current_context_level - target_context_level); 3664 UnchainContexts(current_context_level - target_context_level);
3816 // Record adjusted context level. 3665 // Record adjusted context level.
3817 owner()->nesting_stack()->AdjustContextLevel(target_context_level); 3666 owner()->nesting_stack()->AdjustContextLevel(target_context_level);
3818 } 3667 }
3819 3668
3820
3821 // <Statement> ::= Sequence { scope: LocalScope 3669 // <Statement> ::= Sequence { scope: LocalScope
3822 // nodes: <Statement>* 3670 // nodes: <Statement>*
3823 // label: SourceLabel } 3671 // label: SourceLabel }
3824 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { 3672 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) {
3825 LocalScope* scope = node->scope(); 3673 LocalScope* scope = node->scope();
3826 const Function& function = owner()->function(); 3674 const Function& function = owner()->function();
3827 const intptr_t num_context_variables = 3675 const intptr_t num_context_variables =
3828 (scope != NULL) ? scope->num_context_variables() : 0; 3676 (scope != NULL) ? scope->num_context_variables() : 0;
3829 const bool is_top_level_sequence = 3677 const bool is_top_level_sequence =
3830 node == owner()->parsed_function().node_sequence(); 3678 node == owner()->parsed_function().node_sequence();
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
3991 // Call _asyncSetThreadStackTrace 3839 // Call _asyncSetThreadStackTrace
3992 const intptr_t kTypeArgsLen = 0; 3840 const intptr_t kTypeArgsLen = 0;
3993 StaticCallInstr* call_async_set_thread_stack_trace = new (Z) 3841 StaticCallInstr* call_async_set_thread_stack_trace = new (Z)
3994 StaticCallInstr(node->token_pos().ToSynthetic(), 3842 StaticCallInstr(node->token_pos().ToSynthetic(),
3995 async_set_thread_stack_trace, kTypeArgsLen, 3843 async_set_thread_stack_trace, kTypeArgsLen,
3996 Object::null_array(), arguments, 3844 Object::null_array(), arguments,
3997 owner()->ic_data_array(), owner()->GetNextDeoptId()); 3845 owner()->ic_data_array(), owner()->GetNextDeoptId());
3998 Do(call_async_set_thread_stack_trace); 3846 Do(call_async_set_thread_stack_trace);
3999 } 3847 }
4000 3848
4001
4002 if (FLAG_support_debugger && is_top_level_sequence && 3849 if (FLAG_support_debugger && is_top_level_sequence &&
4003 function.is_debuggable()) { 3850 function.is_debuggable()) {
4004 // Place a debug check at method entry to ensure breaking on a method always 3851 // Place a debug check at method entry to ensure breaking on a method always
4005 // happens, even if there are no assignments/calls/runtimecalls in the first 3852 // happens, even if there are no assignments/calls/runtimecalls in the first
4006 // basic block. Place this check at the last parameter to ensure parameters 3853 // basic block. Place this check at the last parameter to ensure parameters
4007 // are in scope in the debugger at method entry. 3854 // are in scope in the debugger at method entry.
4008 const int num_params = function.NumParameters(); 3855 const int num_params = function.NumParameters();
4009 TokenPosition check_pos = TokenPosition::kNoSource; 3856 TokenPosition check_pos = TokenPosition::kNoSource;
4010 if (num_params > 0) { 3857 if (num_params > 0) {
4011 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); 3858 const LocalVariable& parameter = *scope->VariableAt(num_params - 1);
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
4161 } 4008 }
4162 4009
4163 // If this node sequence is labeled, a break out of the sequence will have 4010 // If this node sequence is labeled, a break out of the sequence will have
4164 // taken care of unchaining the context. 4011 // taken care of unchaining the context.
4165 if (nested_block.break_target() != NULL) { 4012 if (nested_block.break_target() != NULL) {
4166 if (is_open()) Goto(nested_block.break_target()); 4013 if (is_open()) Goto(nested_block.break_target());
4167 exit_ = nested_block.break_target(); 4014 exit_ = nested_block.break_target();
4168 } 4015 }
4169 } 4016 }
4170 4017
4171
4172 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { 4018 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
4173 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); 4019 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)");
4174 // Restores current context from local variable ':saved_try_context_var'. 4020 // Restores current context from local variable ':saved_try_context_var'.
4175 BuildRestoreContext(node->context_var(), node->token_pos()); 4021 BuildRestoreContext(node->context_var(), node->token_pos());
4176 4022
4177 EffectGraphVisitor for_catch(owner()); 4023 EffectGraphVisitor for_catch(owner());
4178 node->VisitChildren(&for_catch); 4024 node->VisitChildren(&for_catch);
4179 Append(for_catch); 4025 Append(for_catch);
4180 } 4026 }
4181 4027
4182
4183 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { 4028 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
4184 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); 4029 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)");
4185 CatchClauseNode* catch_block = node->catch_block(); 4030 CatchClauseNode* catch_block = node->catch_block();
4186 SequenceNode* finally_block = node->finally_block(); 4031 SequenceNode* finally_block = node->finally_block();
4187 if ((finally_block != NULL) && (finally_block->length() == 0)) { 4032 if ((finally_block != NULL) && (finally_block->length() == 0)) {
4188 SequenceNode* catch_sequence = catch_block->sequence(); 4033 SequenceNode* catch_sequence = catch_block->sequence();
4189 if (catch_sequence->length() == 1) { 4034 if (catch_sequence->length() == 1) {
4190 // Check for a single rethrow statement. This only matches the synthetic 4035 // Check for a single rethrow statement. This only matches the synthetic
4191 // catch-clause generated for try-finally. 4036 // catch-clause generated for try-finally.
4192 ThrowNode* throw_node = catch_sequence->NodeAt(0)->AsThrowNode(); 4037 ThrowNode* throw_node = catch_sequence->NodeAt(0)->AsThrowNode();
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
4306 } 4151 }
4307 4152
4308 // Generate code for the finally block if one exists. 4153 // Generate code for the finally block if one exists.
4309 if ((finally_block != NULL) && is_open()) { 4154 if ((finally_block != NULL) && is_open()) {
4310 EffectGraphVisitor for_finally_block(owner()); 4155 EffectGraphVisitor for_finally_block(owner());
4311 finally_block->Visit(&for_finally_block); 4156 finally_block->Visit(&for_finally_block);
4312 Append(for_finally_block); 4157 Append(for_finally_block);
4313 } 4158 }
4314 } 4159 }
4315 4160
4316
4317 // Looks up dynamic method noSuchMethod in target_class 4161 // Looks up dynamic method noSuchMethod in target_class
4318 // (including its super class chain) and builds a static call to it. 4162 // (including its super class chain) and builds a static call to it.
4319 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall( 4163 StaticCallInstr* EffectGraphVisitor::BuildStaticNoSuchMethodCall(
4320 const Class& target_class, 4164 const Class& target_class,
4321 AstNode* receiver, 4165 AstNode* receiver,
4322 const String& method_name, 4166 const String& method_name,
4323 ArgumentListNode* method_arguments, 4167 ArgumentListNode* method_arguments,
4324 bool save_last_arg, 4168 bool save_last_arg,
4325 bool is_super_invocation) { 4169 bool is_super_invocation) {
4326 TokenPosition args_pos = method_arguments->token_pos(); 4170 TokenPosition args_pos = method_arguments->token_pos();
(...skipping 21 matching lines...) Expand all
4348 // We are guaranteed to find noSuchMethod of class Object. 4192 // We are guaranteed to find noSuchMethod of class Object.
4349 ASSERT(!no_such_method_func.IsNull()); 4193 ASSERT(!no_such_method_func.IsNull());
4350 ZoneGrowableArray<PushArgumentInstr*>* push_arguments = 4194 ZoneGrowableArray<PushArgumentInstr*>* push_arguments =
4351 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2); 4195 new (Z) ZoneGrowableArray<PushArgumentInstr*>(2);
4352 BuildPushArguments(*args, push_arguments); 4196 BuildPushArguments(*args, push_arguments);
4353 return new (Z) StaticCallInstr( 4197 return new (Z) StaticCallInstr(
4354 args_pos, no_such_method_func, kTypeArgsLen, Object::null_array(), 4198 args_pos, no_such_method_func, kTypeArgsLen, Object::null_array(),
4355 push_arguments, owner()->ic_data_array(), owner()->GetNextDeoptId()); 4199 push_arguments, owner()->ic_data_array(), owner()->GetNextDeoptId());
4356 } 4200 }
4357 4201
4358
4359 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( 4202 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError(
4360 TokenPosition token_pos, 4203 TokenPosition token_pos,
4361 const Class& function_class, 4204 const Class& function_class,
4362 const String& function_name, 4205 const String& function_name,
4363 ArgumentListNode* function_arguments, 4206 ArgumentListNode* function_arguments,
4364 int invocation_type) { 4207 int invocation_type) {
4365 ZoneGrowableArray<PushArgumentInstr*>* arguments = 4208 ZoneGrowableArray<PushArgumentInstr*>* arguments =
4366 new (Z) ZoneGrowableArray<PushArgumentInstr*>(); 4209 new (Z) ZoneGrowableArray<PushArgumentInstr*>();
4367 // Object receiver, actually a class literal of the unresolved method's owner. 4210 // Object receiver, actually a class literal of the unresolved method's owner.
4368 AbstractType& type = Type::ZoneHandle( 4211 AbstractType& type = Type::ZoneHandle(
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
4415 Z, Resolver::ResolveStatic( 4258 Z, Resolver::ResolveStatic(
4416 cls, Library::PrivateCoreLibName(Symbols::ThrowNew()), 4259 cls, Library::PrivateCoreLibName(Symbols::ThrowNew()),
4417 kTypeArgsLen, arguments->length(), Object::null_array())); 4260 kTypeArgsLen, arguments->length(), Object::null_array()));
4418 ASSERT(!func.IsNull()); 4261 ASSERT(!func.IsNull());
4419 return new (Z) StaticCallInstr(token_pos, func, kTypeArgsLen, 4262 return new (Z) StaticCallInstr(token_pos, func, kTypeArgsLen,
4420 Object::null_array(), // No names. 4263 Object::null_array(), // No names.
4421 arguments, owner()->ic_data_array(), 4264 arguments, owner()->ic_data_array(),
4422 owner()->GetNextDeoptId()); 4265 owner()->GetNextDeoptId());
4423 } 4266 }
4424 4267
4425
4426 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) { 4268 void EffectGraphVisitor::BuildThrowNode(ThrowNode* node) {
4427 if (FLAG_support_debugger) { 4269 if (FLAG_support_debugger) {
4428 if (node->exception()->IsLiteralNode() || 4270 if (node->exception()->IsLiteralNode() ||
4429 node->exception()->IsLoadLocalNode() || 4271 node->exception()->IsLoadLocalNode() ||
4430 node->exception()->IsLoadStaticFieldNode() || 4272 node->exception()->IsLoadStaticFieldNode() ||
4431 node->exception()->IsClosureNode()) { 4273 node->exception()->IsClosureNode()) {
4432 AddInstruction(new (Z) DebugStepCheckInstr(node->token_pos(), 4274 AddInstruction(new (Z) DebugStepCheckInstr(node->token_pos(),
4433 RawPcDescriptors::kRuntimeCall, 4275 RawPcDescriptors::kRuntimeCall,
4434 owner()->GetNextDeoptId())); 4276 owner()->GetNextDeoptId()));
4435 } 4277 }
4436 } 4278 }
4437 ValueGraphVisitor for_exception(owner()); 4279 ValueGraphVisitor for_exception(owner());
4438 node->exception()->Visit(&for_exception); 4280 node->exception()->Visit(&for_exception);
4439 Append(for_exception); 4281 Append(for_exception);
4440 PushArgument(for_exception.value()); 4282 PushArgument(for_exception.value());
4441 Instruction* instr = NULL; 4283 Instruction* instr = NULL;
4442 if (node->stacktrace() == NULL) { 4284 if (node->stacktrace() == NULL) {
4443 instr = new (Z) ThrowInstr(node->token_pos(), owner()->GetNextDeoptId()); 4285 instr = new (Z) ThrowInstr(node->token_pos(), owner()->GetNextDeoptId());
4444 } else { 4286 } else {
4445 ValueGraphVisitor for_stack_trace(owner()); 4287 ValueGraphVisitor for_stack_trace(owner());
4446 node->stacktrace()->Visit(&for_stack_trace); 4288 node->stacktrace()->Visit(&for_stack_trace);
4447 Append(for_stack_trace); 4289 Append(for_stack_trace);
4448 PushArgument(for_stack_trace.value()); 4290 PushArgument(for_stack_trace.value());
4449 instr = new (Z) ReThrowInstr(node->token_pos(), owner()->catch_try_index(), 4291 instr = new (Z) ReThrowInstr(node->token_pos(), owner()->catch_try_index(),
4450 owner()->GetNextDeoptId()); 4292 owner()->GetNextDeoptId());
4451 } 4293 }
4452 AddInstruction(instr); 4294 AddInstruction(instr);
4453 } 4295 }
4454 4296
4455
4456 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) { 4297 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) {
4457 BuildThrowNode(node); 4298 BuildThrowNode(node);
4458 CloseFragment(); 4299 CloseFragment();
4459 } 4300 }
4460 4301
4461
4462 // A throw cannot be part of an expression, however, the parser may replace 4302 // A throw cannot be part of an expression, however, the parser may replace
4463 // certain expression nodes with a throw. In that case generate a literal null 4303 // certain expression nodes with a throw. In that case generate a literal null
4464 // so that the fragment is not closed in the middle of an expression. 4304 // so that the fragment is not closed in the middle of an expression.
4465 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { 4305 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) {
4466 BuildThrowNode(node); 4306 BuildThrowNode(node);
4467 ReturnDefinition( 4307 ReturnDefinition(
4468 new (Z) ConstantInstr(Instance::ZoneHandle(Z, Instance::null()))); 4308 new (Z) ConstantInstr(Instance::ZoneHandle(Z, Instance::null())));
4469 } 4309 }
4470 4310
4471
4472 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { 4311 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
4473 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)"); 4312 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)");
4474 const intptr_t try_index = owner()->try_index(); 4313 const intptr_t try_index = owner()->try_index();
4475 if (try_index >= 0) { 4314 if (try_index >= 0) {
4476 // We are about to generate code for an inlined finally block. Exceptions 4315 // We are about to generate code for an inlined finally block. Exceptions
4477 // thrown in this block of code should be treated as though they are 4316 // thrown in this block of code should be treated as though they are
4478 // thrown not from the current try block but the outer try block if any. 4317 // thrown not from the current try block but the outer try block if any.
4479 intptr_t outer_try_index = node->try_index(); 4318 intptr_t outer_try_index = node->try_index();
4480 owner()->set_try_index(outer_try_index); 4319 owner()->set_try_index(outer_try_index);
4481 } 4320 }
(...skipping 21 matching lines...) Expand all
4503 owner()->GetNextDeoptId()); 4342 owner()->GetNextDeoptId());
4504 for_finally_block.Goto(after_finally); 4343 for_finally_block.Goto(after_finally);
4505 for_finally_block.exit_ = after_finally; 4344 for_finally_block.exit_ = after_finally;
4506 } 4345 }
4507 4346
4508 Goto(finally_entry); 4347 Goto(finally_entry);
4509 AppendFragment(finally_entry, for_finally_block); 4348 AppendFragment(finally_entry, for_finally_block);
4510 exit_ = for_finally_block.exit_; 4349 exit_ = for_finally_block.exit_;
4511 } 4350 }
4512 4351
4513
4514 void EffectGraphVisitor::VisitStopNode(StopNode* node) { 4352 void EffectGraphVisitor::VisitStopNode(StopNode* node) {
4515 AddInstruction(new (Z) StopInstr(node->message())); 4353 AddInstruction(new (Z) StopInstr(node->message()));
4516 } 4354 }
4517 4355
4518
4519 FlowGraph* FlowGraphBuilder::BuildGraph() { 4356 FlowGraph* FlowGraphBuilder::BuildGraph() {
4520 VMTagScope tagScope(thread(), VMTag::kCompileFlowGraphBuilderTagId, 4357 VMTagScope tagScope(thread(), VMTag::kCompileFlowGraphBuilderTagId,
4521 FLAG_profile_vm); 4358 FLAG_profile_vm);
4522 if (FLAG_support_ast_printer && FLAG_print_ast && 4359 if (FLAG_support_ast_printer && FLAG_print_ast &&
4523 FlowGraphPrinter::ShouldPrint(parsed_function().function())) { 4360 FlowGraphPrinter::ShouldPrint(parsed_function().function())) {
4524 // Print the function ast before IL generation. 4361 // Print the function ast before IL generation.
4525 AstPrinter ast_printer; 4362 AstPrinter ast_printer;
4526 ast_printer.PrintFunctionNodes(parsed_function()); 4363 ast_printer.PrintFunctionNodes(parsed_function());
4527 } 4364 }
4528 if (FLAG_support_ast_printer && FLAG_print_scopes && 4365 if (FLAG_support_ast_printer && FLAG_print_scopes &&
(...skipping 18 matching lines...) Expand all
4547 if (osr_id_ != Compiler::kNoOSRDeoptId) { 4384 if (osr_id_ != Compiler::kNoOSRDeoptId) {
4548 graph_entry_->RelinkToOsrEntry(Z, last_used_block_id_); 4385 graph_entry_->RelinkToOsrEntry(Z, last_used_block_id_);
4549 } 4386 }
4550 4387
4551 FlowGraph* graph = 4388 FlowGraph* graph =
4552 new (Z) FlowGraph(parsed_function(), graph_entry_, last_used_block_id_); 4389 new (Z) FlowGraph(parsed_function(), graph_entry_, last_used_block_id_);
4553 graph->set_await_token_positions(await_token_positions_); 4390 graph->set_await_token_positions(await_token_positions_);
4554 return graph; 4391 return graph;
4555 } 4392 }
4556 4393
4557
4558 void FlowGraphBuilder::AppendAwaitTokenPosition(TokenPosition token_pos) { 4394 void FlowGraphBuilder::AppendAwaitTokenPosition(TokenPosition token_pos) {
4559 await_token_positions_->Add(token_pos); 4395 await_token_positions_->Add(token_pos);
4560 } 4396 }
4561 4397
4562
4563 void FlowGraphBuilder::Bailout(const char* reason) const { 4398 void FlowGraphBuilder::Bailout(const char* reason) const {
4564 parsed_function_.Bailout("FlowGraphBuilder", reason); 4399 parsed_function_.Bailout("FlowGraphBuilder", reason);
4565 } 4400 }
4566 4401
4567
4568 bool FlowGraphBuilder::SimpleInstanceOfType(const AbstractType& type) { 4402 bool FlowGraphBuilder::SimpleInstanceOfType(const AbstractType& type) {
4569 // Bail if the type is still uninstantiated at compile time. 4403 // Bail if the type is still uninstantiated at compile time.
4570 if (!type.IsInstantiated()) return false; 4404 if (!type.IsInstantiated()) return false;
4571 4405
4572 // Bail if the type is a function or a Dart Function type. 4406 // Bail if the type is a function or a Dart Function type.
4573 if (type.IsFunctionType() || type.IsDartFunctionType()) return false; 4407 if (type.IsFunctionType() || type.IsDartFunctionType()) return false;
4574 4408
4575 ASSERT(type.HasResolvedTypeClass()); 4409 ASSERT(type.HasResolvedTypeClass());
4576 const Class& type_class = Class::Handle(type.type_class()); 4410 const Class& type_class = Class::Handle(type.type_class());
4577 // Bail if the type has any type parameters. 4411 // Bail if the type has any type parameters.
4578 if (type_class.IsGeneric()) return false; 4412 if (type_class.IsGeneric()) return false;
4579 4413
4580 // Finally a simple class for instance of checking. 4414 // Finally a simple class for instance of checking.
4581 return true; 4415 return true;
4582 } 4416 }
4583 4417
4584 } // namespace dart 4418 } // 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