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 // Class for intrinsifying functions. | 4 // Class for intrinsifying functions. |
5 | 5 |
6 #include "vm/assembler.h" | 6 #include "vm/assembler.h" |
7 #include "vm/compiler.h" | 7 #include "vm/compiler.h" |
8 #include "vm/cpu.h" | 8 #include "vm/cpu.h" |
9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
10 #include "vm/flow_graph.h" | 10 #include "vm/flow_graph.h" |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 | 278 |
279 | 279 |
280 // Notes about the graph intrinsics: | 280 // Notes about the graph intrinsics: |
281 // | 281 // |
282 // IR instructions which would jump to a deoptimization sequence on failure | 282 // IR instructions which would jump to a deoptimization sequence on failure |
283 // instead branch to the intrinsic slow path. | 283 // instead branch to the intrinsic slow path. |
284 // | 284 // |
285 class BlockBuilder : public ValueObject { | 285 class BlockBuilder : public ValueObject { |
286 public: | 286 public: |
287 BlockBuilder(FlowGraph* flow_graph, TargetEntryInstr* entry) | 287 BlockBuilder(FlowGraph* flow_graph, TargetEntryInstr* entry) |
288 : flow_graph_(flow_graph), entry_(entry), current_(entry) {} | 288 : flow_graph_(flow_graph), |
| 289 entry_(entry), |
| 290 current_(entry), |
| 291 fall_through_env_(new Environment(0, |
| 292 0, |
| 293 Thread::kNoDeoptId, |
| 294 flow_graph->parsed_function(), |
| 295 NULL)) {} |
289 | 296 |
290 Definition* AddToInitialDefinitions(Definition* def) { | 297 Definition* AddToInitialDefinitions(Definition* def) { |
291 def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); | 298 def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); |
292 flow_graph_->AddToInitialDefinitions(def); | 299 flow_graph_->AddToInitialDefinitions(def); |
293 return def; | 300 return def; |
294 } | 301 } |
295 | 302 |
296 Definition* AddDefinition(Definition* def) { | 303 Definition* AddDefinition(Definition* def) { |
297 def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); | 304 def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index()); |
298 current_ = current_->AppendInstruction(def); | 305 AddInstruction(def); |
299 return def; | 306 return def; |
300 } | 307 } |
301 | 308 |
302 Instruction* AddInstruction(Instruction* instr) { | 309 Instruction* AddInstruction(Instruction* instr) { |
| 310 if (instr->ComputeCanDeoptimize()) { |
| 311 // Since we use the presence of an environment to determine if an |
| 312 // instructions can deoptimize, we need an empty enviroment for |
| 313 // instructions that "deoptimize" to the intrinsic fall-through code. |
| 314 instr->SetEnvironment(fall_through_env_); |
| 315 } |
303 current_ = current_->AppendInstruction(instr); | 316 current_ = current_->AppendInstruction(instr); |
304 return instr; | 317 return instr; |
305 } | 318 } |
306 | 319 |
307 void AddIntrinsicReturn(Value* value) { | 320 void AddIntrinsicReturn(Value* value) { |
308 ReturnInstr* instr = new ReturnInstr(TokenPos(), value); | 321 ReturnInstr* instr = new ReturnInstr(TokenPos(), value); |
309 AddInstruction(instr); | 322 AddInstruction(instr); |
310 entry_->set_last_instruction(instr); | 323 entry_->set_last_instruction(instr); |
311 } | 324 } |
312 | 325 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 new InvokeMathCFunctionInstr(args, Thread::kNoDeoptId, recognized_kind, | 366 new InvokeMathCFunctionInstr(args, Thread::kNoDeoptId, recognized_kind, |
354 TokenPos()); | 367 TokenPos()); |
355 AddDefinition(invoke_math_c_function); | 368 AddDefinition(invoke_math_c_function); |
356 return invoke_math_c_function; | 369 return invoke_math_c_function; |
357 } | 370 } |
358 | 371 |
359 | 372 |
360 FlowGraph* flow_graph_; | 373 FlowGraph* flow_graph_; |
361 BlockEntryInstr* entry_; | 374 BlockEntryInstr* entry_; |
362 Instruction* current_; | 375 Instruction* current_; |
| 376 Environment* fall_through_env_; |
363 }; | 377 }; |
364 | 378 |
365 | 379 |
366 static void PrepareIndexedOp(BlockBuilder* builder, | 380 static void PrepareIndexedOp(BlockBuilder* builder, |
367 Definition* array, | 381 Definition* array, |
368 Definition* index, | 382 Definition* index, |
369 intptr_t length_offset) { | 383 intptr_t length_offset) { |
370 Definition* length = builder->AddDefinition(new LoadFieldInstr( | 384 Definition* length = builder->AddDefinition(new LoadFieldInstr( |
371 new Value(array), length_offset, Type::ZoneHandle(Type::SmiType()), | 385 new Value(array), length_offset, Type::ZoneHandle(Type::SmiType()), |
372 TokenPosition::kNoSource)); | 386 TokenPosition::kNoSource)); |
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 } | 1181 } |
1168 | 1182 |
1169 | 1183 |
1170 void Intrinsifier::RegExp_ExecuteMatchSticky(Assembler* assembler) { | 1184 void Intrinsifier::RegExp_ExecuteMatchSticky(Assembler* assembler) { |
1171 IntrinsifyRegExpExecuteMatch(assembler, /*sticky=*/true); | 1185 IntrinsifyRegExpExecuteMatch(assembler, /*sticky=*/true); |
1172 } | 1186 } |
1173 #endif // !defined(TARGET_ARCH_DBC) | 1187 #endif // !defined(TARGET_ARCH_DBC) |
1174 | 1188 |
1175 | 1189 |
1176 } // namespace dart | 1190 } // namespace dart |
OLD | NEW |