OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
6 | 6 |
7 #include "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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |