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/intrinsifier.h" | 7 #include "vm/intrinsifier.h" |
8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
9 #include "vm/object.h" | 9 #include "vm/object.h" |
10 #include "vm/symbols.h" | 10 #include "vm/symbols.h" |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 } | 126 } |
127 | 127 |
128 | 128 |
129 bool Intrinsifier::GraphIntrinsify(const ParsedFunction& parsed_function, | 129 bool Intrinsifier::GraphIntrinsify(const ParsedFunction& parsed_function, |
130 FlowGraphCompiler* compiler) { | 130 FlowGraphCompiler* compiler) { |
131 ZoneGrowableArray<const ICData*>* ic_data_array = | 131 ZoneGrowableArray<const ICData*>* ic_data_array = |
132 new ZoneGrowableArray<const ICData*>(); | 132 new ZoneGrowableArray<const ICData*>(); |
133 FlowGraphBuilder builder(parsed_function, | 133 FlowGraphBuilder builder(parsed_function, |
134 *ic_data_array, | 134 *ic_data_array, |
135 NULL, // NULL = not inlining. | 135 NULL, // NULL = not inlining. |
136 Isolate::kNoDeoptId); // No OSR id. | 136 Thread::kNoDeoptId); // No OSR id. |
137 | 137 |
138 intptr_t block_id = builder.AllocateBlockId(); | 138 intptr_t block_id = builder.AllocateBlockId(); |
139 TargetEntryInstr* normal_entry = | 139 TargetEntryInstr* normal_entry = |
140 new TargetEntryInstr(block_id, | 140 new TargetEntryInstr(block_id, |
141 CatchClauseNode::kInvalidTryIndex); | 141 CatchClauseNode::kInvalidTryIndex); |
142 GraphEntryInstr* graph_entry = new GraphEntryInstr( | 142 GraphEntryInstr* graph_entry = new GraphEntryInstr( |
143 parsed_function, normal_entry, Isolate::kNoDeoptId); // No OSR id. | 143 parsed_function, normal_entry, Thread::kNoDeoptId); // No OSR id. |
144 FlowGraph* graph = new FlowGraph(parsed_function, graph_entry, block_id); | 144 FlowGraph* graph = new FlowGraph(parsed_function, graph_entry, block_id); |
145 const Function& function = parsed_function.function(); | 145 const Function& function = parsed_function.function(); |
146 switch (function.recognized_kind()) { | 146 switch (function.recognized_kind()) { |
147 #define EMIT_CASE(class_name, function_name, enum_name, fp) \ | 147 #define EMIT_CASE(class_name, function_name, enum_name, fp) \ |
148 case MethodRecognizer::k##enum_name: \ | 148 case MethodRecognizer::k##enum_name: \ |
149 if (!Build_##enum_name(graph)) return false; \ | 149 if (!Build_##enum_name(graph)) return false; \ |
150 break; | 150 break; |
151 | 151 |
152 GRAPH_INTRINSICS_LIST(EMIT_CASE); | 152 GRAPH_INTRINSICS_LIST(EMIT_CASE); |
153 default: | 153 default: |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 return flow_graph_->function().token_pos(); | 267 return flow_graph_->function().token_pos(); |
268 } | 268 } |
269 | 269 |
270 Definition* AddNullDefinition() { | 270 Definition* AddNullDefinition() { |
271 return AddDefinition( | 271 return AddDefinition( |
272 new ConstantInstr(Object::ZoneHandle(Object::null()))); | 272 new ConstantInstr(Object::ZoneHandle(Object::null()))); |
273 } | 273 } |
274 | 274 |
275 Definition* AddUnboxInstr(Representation rep, Value* value) { | 275 Definition* AddUnboxInstr(Representation rep, Value* value) { |
276 Definition* unboxed_value = AddDefinition( | 276 Definition* unboxed_value = AddDefinition( |
277 UnboxInstr::Create(rep, value, Isolate::kNoDeoptId)); | 277 UnboxInstr::Create(rep, value, Thread::kNoDeoptId)); |
278 // Manually adjust reaching type because there is no type propagation | 278 // Manually adjust reaching type because there is no type propagation |
279 // when building intrinsics. | 279 // when building intrinsics. |
280 unboxed_value->AsUnbox()->value()->SetReachingType(ZoneCompileType::Wrap( | 280 unboxed_value->AsUnbox()->value()->SetReachingType(ZoneCompileType::Wrap( |
281 CompileType::FromCid(CidForRepresentation(rep)))); | 281 CompileType::FromCid(CidForRepresentation(rep)))); |
282 return unboxed_value; | 282 return unboxed_value; |
283 } | 283 } |
284 | 284 |
285 private: | 285 private: |
286 FlowGraph* flow_graph_; | 286 FlowGraph* flow_graph_; |
287 BlockEntryInstr* entry_; | 287 BlockEntryInstr* entry_; |
288 Instruction* current_; | 288 Instruction* current_; |
289 }; | 289 }; |
290 | 290 |
291 | 291 |
292 static void PrepareIndexedOp(BlockBuilder* builder, | 292 static void PrepareIndexedOp(BlockBuilder* builder, |
293 Definition* array, | 293 Definition* array, |
294 Definition* index, | 294 Definition* index, |
295 intptr_t length_offset) { | 295 intptr_t length_offset) { |
296 intptr_t token_pos = builder->TokenPos(); | 296 intptr_t token_pos = builder->TokenPos(); |
297 builder->AddInstruction( | 297 builder->AddInstruction( |
298 new CheckSmiInstr(new Value(index), | 298 new CheckSmiInstr(new Value(index), |
299 Isolate::kNoDeoptId, | 299 Thread::kNoDeoptId, |
300 token_pos)); | 300 token_pos)); |
301 | 301 |
302 Definition* length = builder->AddDefinition( | 302 Definition* length = builder->AddDefinition( |
303 new LoadFieldInstr(new Value(array), | 303 new LoadFieldInstr(new Value(array), |
304 length_offset, | 304 length_offset, |
305 Type::ZoneHandle(Type::SmiType()), | 305 Type::ZoneHandle(Type::SmiType()), |
306 Scanner::kNoSourcePos)); | 306 Scanner::kNoSourcePos)); |
307 builder->AddInstruction( | 307 builder->AddInstruction( |
308 new CheckArrayBoundInstr(new Value(length), | 308 new CheckArrayBoundInstr(new Value(length), |
309 new Value(index), | 309 new Value(index), |
310 Isolate::kNoDeoptId)); | 310 Thread::kNoDeoptId)); |
311 } | 311 } |
312 | 312 |
313 | 313 |
314 bool Intrinsifier::Build_ObjectArrayGetIndexed(FlowGraph* flow_graph) { | 314 bool Intrinsifier::Build_ObjectArrayGetIndexed(FlowGraph* flow_graph) { |
315 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | 315 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
316 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 316 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
317 BlockBuilder builder(flow_graph, normal_entry); | 317 BlockBuilder builder(flow_graph, normal_entry); |
318 | 318 |
319 Definition* index = builder.AddParameter(1); | 319 Definition* index = builder.AddParameter(1); |
320 Definition* array = builder.AddParameter(2); | 320 Definition* array = builder.AddParameter(2); |
321 | 321 |
322 PrepareIndexedOp(&builder, array, index, Array::length_offset()); | 322 PrepareIndexedOp(&builder, array, index, Array::length_offset()); |
323 | 323 |
324 Definition* result = builder.AddDefinition( | 324 Definition* result = builder.AddDefinition( |
325 new LoadIndexedInstr(new Value(array), | 325 new LoadIndexedInstr(new Value(array), |
326 new Value(index), | 326 new Value(index), |
327 Instance::ElementSizeFor(kArrayCid), // index scale | 327 Instance::ElementSizeFor(kArrayCid), // index scale |
328 kArrayCid, | 328 kArrayCid, |
329 Isolate::kNoDeoptId, | 329 Thread::kNoDeoptId, |
330 builder.TokenPos())); | 330 builder.TokenPos())); |
331 builder.AddIntrinsicReturn(new Value(result)); | 331 builder.AddIntrinsicReturn(new Value(result)); |
332 return true; | 332 return true; |
333 } | 333 } |
334 | 334 |
335 | 335 |
336 bool Intrinsifier::Build_ImmutableArrayGetIndexed(FlowGraph* flow_graph) { | 336 bool Intrinsifier::Build_ImmutableArrayGetIndexed(FlowGraph* flow_graph) { |
337 return Build_ObjectArrayGetIndexed(flow_graph); | 337 return Build_ObjectArrayGetIndexed(flow_graph); |
338 } | 338 } |
339 | 339 |
340 | 340 |
341 bool Intrinsifier::Build_Uint8ArrayGetIndexed(FlowGraph* flow_graph) { | 341 bool Intrinsifier::Build_Uint8ArrayGetIndexed(FlowGraph* flow_graph) { |
342 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | 342 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
343 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 343 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
344 BlockBuilder builder(flow_graph, normal_entry); | 344 BlockBuilder builder(flow_graph, normal_entry); |
345 | 345 |
346 Definition* index = builder.AddParameter(1); | 346 Definition* index = builder.AddParameter(1); |
347 Definition* array = builder.AddParameter(2); | 347 Definition* array = builder.AddParameter(2); |
348 | 348 |
349 PrepareIndexedOp(&builder, array, index, TypedData::length_offset()); | 349 PrepareIndexedOp(&builder, array, index, TypedData::length_offset()); |
350 | 350 |
351 Definition* result = builder.AddDefinition( | 351 Definition* result = builder.AddDefinition( |
352 new LoadIndexedInstr(new Value(array), | 352 new LoadIndexedInstr(new Value(array), |
353 new Value(index), | 353 new Value(index), |
354 1, // index scale | 354 1, // index scale |
355 kTypedDataUint8ArrayCid, | 355 kTypedDataUint8ArrayCid, |
356 Isolate::kNoDeoptId, | 356 Thread::kNoDeoptId, |
357 builder.TokenPos())); | 357 builder.TokenPos())); |
358 builder.AddIntrinsicReturn(new Value(result)); | 358 builder.AddIntrinsicReturn(new Value(result)); |
359 return true; | 359 return true; |
360 } | 360 } |
361 | 361 |
362 | 362 |
363 bool Intrinsifier::Build_ExternalUint8ArrayGetIndexed(FlowGraph* flow_graph) { | 363 bool Intrinsifier::Build_ExternalUint8ArrayGetIndexed(FlowGraph* flow_graph) { |
364 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | 364 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
365 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 365 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
366 BlockBuilder builder(flow_graph, normal_entry); | 366 BlockBuilder builder(flow_graph, normal_entry); |
367 | 367 |
368 Definition* index = builder.AddParameter(1); | 368 Definition* index = builder.AddParameter(1); |
369 Definition* array = builder.AddParameter(2); | 369 Definition* array = builder.AddParameter(2); |
370 | 370 |
371 PrepareIndexedOp(&builder, array, index, ExternalTypedData::length_offset()); | 371 PrepareIndexedOp(&builder, array, index, ExternalTypedData::length_offset()); |
372 | 372 |
373 Definition* elements = builder.AddDefinition( | 373 Definition* elements = builder.AddDefinition( |
374 new LoadUntaggedInstr(new Value(array), | 374 new LoadUntaggedInstr(new Value(array), |
375 ExternalTypedData::data_offset())); | 375 ExternalTypedData::data_offset())); |
376 Definition* result = builder.AddDefinition( | 376 Definition* result = builder.AddDefinition( |
377 new LoadIndexedInstr(new Value(elements), | 377 new LoadIndexedInstr(new Value(elements), |
378 new Value(index), | 378 new Value(index), |
379 1, // index scale | 379 1, // index scale |
380 kExternalTypedDataUint8ArrayCid, | 380 kExternalTypedDataUint8ArrayCid, |
381 Isolate::kNoDeoptId, | 381 Thread::kNoDeoptId, |
382 builder.TokenPos())); | 382 builder.TokenPos())); |
383 builder.AddIntrinsicReturn(new Value(result)); | 383 builder.AddIntrinsicReturn(new Value(result)); |
384 return true; | 384 return true; |
385 } | 385 } |
386 | 386 |
387 | 387 |
388 bool Intrinsifier::Build_Uint8ArraySetIndexed(FlowGraph* flow_graph) { | 388 bool Intrinsifier::Build_Uint8ArraySetIndexed(FlowGraph* flow_graph) { |
389 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | 389 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
390 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 390 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
391 BlockBuilder builder(flow_graph, normal_entry); | 391 BlockBuilder builder(flow_graph, normal_entry); |
392 | 392 |
393 Definition* value = builder.AddParameter(1); | 393 Definition* value = builder.AddParameter(1); |
394 Definition* index = builder.AddParameter(2); | 394 Definition* index = builder.AddParameter(2); |
395 Definition* array = builder.AddParameter(3); | 395 Definition* array = builder.AddParameter(3); |
396 | 396 |
397 PrepareIndexedOp(&builder, array, index, TypedData::length_offset()); | 397 PrepareIndexedOp(&builder, array, index, TypedData::length_offset()); |
398 | 398 |
399 builder.AddInstruction( | 399 builder.AddInstruction( |
400 new CheckSmiInstr(new Value(value), | 400 new CheckSmiInstr(new Value(value), |
401 Isolate::kNoDeoptId, | 401 Thread::kNoDeoptId, |
402 builder.TokenPos())); | 402 builder.TokenPos())); |
403 | 403 |
404 builder.AddInstruction( | 404 builder.AddInstruction( |
405 new StoreIndexedInstr(new Value(array), | 405 new StoreIndexedInstr(new Value(array), |
406 new Value(index), | 406 new Value(index), |
407 new Value(value), | 407 new Value(value), |
408 kNoStoreBarrier, | 408 kNoStoreBarrier, |
409 1, // index scale | 409 1, // index scale |
410 kTypedDataUint8ArrayCid, | 410 kTypedDataUint8ArrayCid, |
411 Isolate::kNoDeoptId, | 411 Thread::kNoDeoptId, |
412 builder.TokenPos())); | 412 builder.TokenPos())); |
413 // Return null. | 413 // Return null. |
414 Definition* null_def = builder.AddNullDefinition(); | 414 Definition* null_def = builder.AddNullDefinition(); |
415 builder.AddIntrinsicReturn(new Value(null_def)); | 415 builder.AddIntrinsicReturn(new Value(null_def)); |
416 return true; | 416 return true; |
417 } | 417 } |
418 | 418 |
419 | 419 |
420 bool Intrinsifier::Build_ExternalUint8ArraySetIndexed(FlowGraph* flow_graph) { | 420 bool Intrinsifier::Build_ExternalUint8ArraySetIndexed(FlowGraph* flow_graph) { |
421 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | 421 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
422 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 422 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
423 BlockBuilder builder(flow_graph, normal_entry); | 423 BlockBuilder builder(flow_graph, normal_entry); |
424 | 424 |
425 Definition* value = builder.AddParameter(1); | 425 Definition* value = builder.AddParameter(1); |
426 Definition* index = builder.AddParameter(2); | 426 Definition* index = builder.AddParameter(2); |
427 Definition* array = builder.AddParameter(3); | 427 Definition* array = builder.AddParameter(3); |
428 | 428 |
429 PrepareIndexedOp(&builder, array, index, ExternalTypedData::length_offset()); | 429 PrepareIndexedOp(&builder, array, index, ExternalTypedData::length_offset()); |
430 | 430 |
431 builder.AddInstruction( | 431 builder.AddInstruction( |
432 new CheckSmiInstr(new Value(value), | 432 new CheckSmiInstr(new Value(value), |
433 Isolate::kNoDeoptId, | 433 Thread::kNoDeoptId, |
434 builder.TokenPos())); | 434 builder.TokenPos())); |
435 Definition* elements = builder.AddDefinition( | 435 Definition* elements = builder.AddDefinition( |
436 new LoadUntaggedInstr(new Value(array), | 436 new LoadUntaggedInstr(new Value(array), |
437 ExternalTypedData::data_offset())); | 437 ExternalTypedData::data_offset())); |
438 builder.AddInstruction( | 438 builder.AddInstruction( |
439 new StoreIndexedInstr(new Value(elements), | 439 new StoreIndexedInstr(new Value(elements), |
440 new Value(index), | 440 new Value(index), |
441 new Value(value), | 441 new Value(value), |
442 kNoStoreBarrier, | 442 kNoStoreBarrier, |
443 1, // index scale | 443 1, // index scale |
444 kExternalTypedDataUint8ArrayCid, | 444 kExternalTypedDataUint8ArrayCid, |
445 Isolate::kNoDeoptId, | 445 Thread::kNoDeoptId, |
446 builder.TokenPos())); | 446 builder.TokenPos())); |
447 // Return null. | 447 // Return null. |
448 Definition* null_def = builder.AddNullDefinition(); | 448 Definition* null_def = builder.AddNullDefinition(); |
449 builder.AddIntrinsicReturn(new Value(null_def)); | 449 builder.AddIntrinsicReturn(new Value(null_def)); |
450 return true; | 450 return true; |
451 } | 451 } |
452 | 452 |
453 | 453 |
454 bool Intrinsifier::Build_Uint32ArraySetIndexed(FlowGraph* flow_graph) { | 454 bool Intrinsifier::Build_Uint32ArraySetIndexed(FlowGraph* flow_graph) { |
455 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | 455 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
456 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 456 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
457 BlockBuilder builder(flow_graph, normal_entry); | 457 BlockBuilder builder(flow_graph, normal_entry); |
458 | 458 |
459 Definition* value = builder.AddParameter(1); | 459 Definition* value = builder.AddParameter(1); |
460 Definition* index = builder.AddParameter(2); | 460 Definition* index = builder.AddParameter(2); |
461 Definition* array = builder.AddParameter(3); | 461 Definition* array = builder.AddParameter(3); |
462 | 462 |
463 PrepareIndexedOp(&builder, array, index, TypedData::length_offset()); | 463 PrepareIndexedOp(&builder, array, index, TypedData::length_offset()); |
464 | 464 |
465 Definition* unboxed_value = | 465 Definition* unboxed_value = |
466 builder.AddUnboxInstr(kUnboxedUint32, new Value(value)); | 466 builder.AddUnboxInstr(kUnboxedUint32, new Value(value)); |
467 | 467 |
468 builder.AddInstruction( | 468 builder.AddInstruction( |
469 new StoreIndexedInstr(new Value(array), | 469 new StoreIndexedInstr(new Value(array), |
470 new Value(index), | 470 new Value(index), |
471 new Value(unboxed_value), | 471 new Value(unboxed_value), |
472 kNoStoreBarrier, | 472 kNoStoreBarrier, |
473 4, // index scale | 473 4, // index scale |
474 kTypedDataUint32ArrayCid, | 474 kTypedDataUint32ArrayCid, |
475 Isolate::kNoDeoptId, | 475 Thread::kNoDeoptId, |
476 builder.TokenPos())); | 476 builder.TokenPos())); |
477 // Return null. | 477 // Return null. |
478 Definition* null_def = builder.AddNullDefinition(); | 478 Definition* null_def = builder.AddNullDefinition(); |
479 builder.AddIntrinsicReturn(new Value(null_def)); | 479 builder.AddIntrinsicReturn(new Value(null_def)); |
480 return true; | 480 return true; |
481 } | 481 } |
482 | 482 |
483 | 483 |
484 bool Intrinsifier::Build_Uint32ArrayGetIndexed(FlowGraph* flow_graph) { | 484 bool Intrinsifier::Build_Uint32ArrayGetIndexed(FlowGraph* flow_graph) { |
485 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | 485 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
486 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 486 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
487 BlockBuilder builder(flow_graph, normal_entry); | 487 BlockBuilder builder(flow_graph, normal_entry); |
488 | 488 |
489 Definition* index = builder.AddParameter(1); | 489 Definition* index = builder.AddParameter(1); |
490 Definition* array = builder.AddParameter(2); | 490 Definition* array = builder.AddParameter(2); |
491 | 491 |
492 PrepareIndexedOp(&builder, array, index, TypedData::length_offset()); | 492 PrepareIndexedOp(&builder, array, index, TypedData::length_offset()); |
493 | 493 |
494 Definition* unboxed_value = builder.AddDefinition( | 494 Definition* unboxed_value = builder.AddDefinition( |
495 new LoadIndexedInstr(new Value(array), | 495 new LoadIndexedInstr(new Value(array), |
496 new Value(index), | 496 new Value(index), |
497 4, // index scale | 497 4, // index scale |
498 kTypedDataUint32ArrayCid, | 498 kTypedDataUint32ArrayCid, |
499 Isolate::kNoDeoptId, | 499 Thread::kNoDeoptId, |
500 builder.TokenPos())); | 500 builder.TokenPos())); |
501 Definition* result = builder.AddDefinition( | 501 Definition* result = builder.AddDefinition( |
502 BoxInstr::Create(kUnboxedUint32, new Value(unboxed_value))); | 502 BoxInstr::Create(kUnboxedUint32, new Value(unboxed_value))); |
503 builder.AddIntrinsicReturn(new Value(result)); | 503 builder.AddIntrinsicReturn(new Value(result)); |
504 return true; | 504 return true; |
505 } | 505 } |
506 | 506 |
507 | 507 |
508 bool Intrinsifier::Build_Float64ArraySetIndexed(FlowGraph* flow_graph) { | 508 bool Intrinsifier::Build_Float64ArraySetIndexed(FlowGraph* flow_graph) { |
509 if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false; | 509 if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false; |
510 | 510 |
511 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | 511 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
512 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 512 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
513 BlockBuilder builder(flow_graph, normal_entry); | 513 BlockBuilder builder(flow_graph, normal_entry); |
514 | 514 |
515 Definition* value = builder.AddParameter(1); | 515 Definition* value = builder.AddParameter(1); |
516 Definition* index = builder.AddParameter(2); | 516 Definition* index = builder.AddParameter(2); |
517 Definition* array = builder.AddParameter(3); | 517 Definition* array = builder.AddParameter(3); |
518 | 518 |
519 PrepareIndexedOp(&builder, array, index, TypedData::length_offset()); | 519 PrepareIndexedOp(&builder, array, index, TypedData::length_offset()); |
520 | 520 |
521 const ICData& value_check = ICData::ZoneHandle(ICData::New( | 521 const ICData& value_check = ICData::ZoneHandle(ICData::New( |
522 flow_graph->function(), | 522 flow_graph->function(), |
523 String::Handle(flow_graph->function().name()), | 523 String::Handle(flow_graph->function().name()), |
524 Object::empty_array(), // Dummy args. descr. | 524 Object::empty_array(), // Dummy args. descr. |
525 Isolate::kNoDeoptId, | 525 Thread::kNoDeoptId, |
526 1)); | 526 1)); |
527 value_check.AddReceiverCheck(kDoubleCid, flow_graph->function()); | 527 value_check.AddReceiverCheck(kDoubleCid, flow_graph->function()); |
528 builder.AddInstruction( | 528 builder.AddInstruction( |
529 new CheckClassInstr(new Value(value), | 529 new CheckClassInstr(new Value(value), |
530 Isolate::kNoDeoptId, | 530 Thread::kNoDeoptId, |
531 value_check, | 531 value_check, |
532 builder.TokenPos())); | 532 builder.TokenPos())); |
533 Definition* double_value = | 533 Definition* double_value = |
534 builder.AddUnboxInstr(kUnboxedDouble, new Value(value)); | 534 builder.AddUnboxInstr(kUnboxedDouble, new Value(value)); |
535 | 535 |
536 builder.AddInstruction( | 536 builder.AddInstruction( |
537 new StoreIndexedInstr(new Value(array), | 537 new StoreIndexedInstr(new Value(array), |
538 new Value(index), | 538 new Value(index), |
539 new Value(double_value), | 539 new Value(double_value), |
540 kNoStoreBarrier, | 540 kNoStoreBarrier, |
541 8, // index scale | 541 8, // index scale |
542 kTypedDataFloat64ArrayCid, | 542 kTypedDataFloat64ArrayCid, |
543 Isolate::kNoDeoptId, | 543 Thread::kNoDeoptId, |
544 builder.TokenPos())); | 544 builder.TokenPos())); |
545 // Return null. | 545 // Return null. |
546 Definition* null_def = builder.AddNullDefinition(); | 546 Definition* null_def = builder.AddNullDefinition(); |
547 builder.AddIntrinsicReturn(new Value(null_def)); | 547 builder.AddIntrinsicReturn(new Value(null_def)); |
548 return true; | 548 return true; |
549 } | 549 } |
550 | 550 |
551 | 551 |
552 bool Intrinsifier::Build_Float64ArrayGetIndexed(FlowGraph* flow_graph) { | 552 bool Intrinsifier::Build_Float64ArrayGetIndexed(FlowGraph* flow_graph) { |
553 if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false; | 553 if (!FlowGraphCompiler::SupportsUnboxedDoubles()) return false; |
554 | 554 |
555 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | 555 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
556 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 556 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
557 BlockBuilder builder(flow_graph, normal_entry); | 557 BlockBuilder builder(flow_graph, normal_entry); |
558 | 558 |
559 Definition* index = builder.AddParameter(1); | 559 Definition* index = builder.AddParameter(1); |
560 Definition* array = builder.AddParameter(2); | 560 Definition* array = builder.AddParameter(2); |
561 | 561 |
562 PrepareIndexedOp(&builder, array, index, TypedData::length_offset()); | 562 PrepareIndexedOp(&builder, array, index, TypedData::length_offset()); |
563 | 563 |
564 Definition* unboxed_value = builder.AddDefinition( | 564 Definition* unboxed_value = builder.AddDefinition( |
565 new LoadIndexedInstr(new Value(array), | 565 new LoadIndexedInstr(new Value(array), |
566 new Value(index), | 566 new Value(index), |
567 8, // index scale | 567 8, // index scale |
568 kTypedDataFloat64ArrayCid, | 568 kTypedDataFloat64ArrayCid, |
569 Isolate::kNoDeoptId, | 569 Thread::kNoDeoptId, |
570 builder.TokenPos())); | 570 builder.TokenPos())); |
571 Definition* result = builder.AddDefinition( | 571 Definition* result = builder.AddDefinition( |
572 BoxInstr::Create(kUnboxedDouble, new Value(unboxed_value))); | 572 BoxInstr::Create(kUnboxedDouble, new Value(unboxed_value))); |
573 builder.AddIntrinsicReturn(new Value(result)); | 573 builder.AddIntrinsicReturn(new Value(result)); |
574 return true; | 574 return true; |
575 } | 575 } |
576 | 576 |
577 | 577 |
578 static bool BuildBinaryFloat32x4Op(FlowGraph* flow_graph, Token::Kind kind) { | 578 static bool BuildBinaryFloat32x4Op(FlowGraph* flow_graph, Token::Kind kind) { |
579 if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false; | 579 if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false; |
580 | 580 |
581 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | 581 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
582 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 582 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
583 BlockBuilder builder(flow_graph, normal_entry); | 583 BlockBuilder builder(flow_graph, normal_entry); |
584 | 584 |
585 Definition* right = builder.AddParameter(1); | 585 Definition* right = builder.AddParameter(1); |
586 Definition* left = builder.AddParameter(2); | 586 Definition* left = builder.AddParameter(2); |
587 | 587 |
588 const ICData& value_check = ICData::ZoneHandle(ICData::New( | 588 const ICData& value_check = ICData::ZoneHandle(ICData::New( |
589 flow_graph->function(), | 589 flow_graph->function(), |
590 String::Handle(flow_graph->function().name()), | 590 String::Handle(flow_graph->function().name()), |
591 Object::empty_array(), // Dummy args. descr. | 591 Object::empty_array(), // Dummy args. descr. |
592 Isolate::kNoDeoptId, | 592 Thread::kNoDeoptId, |
593 1)); | 593 1)); |
594 value_check.AddReceiverCheck(kFloat32x4Cid, flow_graph->function()); | 594 value_check.AddReceiverCheck(kFloat32x4Cid, flow_graph->function()); |
595 // Check argument. Receiver (left) is known to be a Float32x4. | 595 // Check argument. Receiver (left) is known to be a Float32x4. |
596 builder.AddInstruction( | 596 builder.AddInstruction( |
597 new CheckClassInstr(new Value(right), | 597 new CheckClassInstr(new Value(right), |
598 Isolate::kNoDeoptId, | 598 Thread::kNoDeoptId, |
599 value_check, | 599 value_check, |
600 builder.TokenPos())); | 600 builder.TokenPos())); |
601 Definition* left_simd = | 601 Definition* left_simd = |
602 builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(left)); | 602 builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(left)); |
603 | 603 |
604 Definition* right_simd = | 604 Definition* right_simd = |
605 builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(right)); | 605 builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(right)); |
606 | 606 |
607 Definition* unboxed_result = builder.AddDefinition( | 607 Definition* unboxed_result = builder.AddDefinition( |
608 new BinaryFloat32x4OpInstr(kind, | 608 new BinaryFloat32x4OpInstr(kind, |
609 new Value(left_simd), | 609 new Value(left_simd), |
610 new Value(right_simd), | 610 new Value(right_simd), |
611 Isolate::kNoDeoptId)); | 611 Thread::kNoDeoptId)); |
612 Definition* result = builder.AddDefinition( | 612 Definition* result = builder.AddDefinition( |
613 BoxInstr::Create(kUnboxedFloat32x4, new Value(unboxed_result))); | 613 BoxInstr::Create(kUnboxedFloat32x4, new Value(unboxed_result))); |
614 builder.AddIntrinsicReturn(new Value(result)); | 614 builder.AddIntrinsicReturn(new Value(result)); |
615 return true; | 615 return true; |
616 } | 616 } |
617 | 617 |
618 | 618 |
619 bool Intrinsifier::Build_Float32x4Mul(FlowGraph* flow_graph) { | 619 bool Intrinsifier::Build_Float32x4Mul(FlowGraph* flow_graph) { |
620 return BuildBinaryFloat32x4Op(flow_graph, Token::kMUL); | 620 return BuildBinaryFloat32x4Op(flow_graph, Token::kMUL); |
621 } | 621 } |
(...skipping 18 matching lines...) Expand all Loading... |
640 | 640 |
641 Definition* receiver = builder.AddParameter(1); | 641 Definition* receiver = builder.AddParameter(1); |
642 | 642 |
643 Definition* unboxed_receiver = | 643 Definition* unboxed_receiver = |
644 builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(receiver)); | 644 builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(receiver)); |
645 | 645 |
646 Definition* unboxed_result = builder.AddDefinition( | 646 Definition* unboxed_result = builder.AddDefinition( |
647 new Simd32x4ShuffleInstr(kind, | 647 new Simd32x4ShuffleInstr(kind, |
648 new Value(unboxed_receiver), | 648 new Value(unboxed_receiver), |
649 0, | 649 0, |
650 Isolate::kNoDeoptId)); | 650 Thread::kNoDeoptId)); |
651 | 651 |
652 Definition* result = builder.AddDefinition( | 652 Definition* result = builder.AddDefinition( |
653 BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result))); | 653 BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result))); |
654 builder.AddIntrinsicReturn(new Value(result)); | 654 builder.AddIntrinsicReturn(new Value(result)); |
655 return true; | 655 return true; |
656 } | 656 } |
657 | 657 |
658 | 658 |
659 bool Intrinsifier::Build_Float32x4ShuffleX(FlowGraph* flow_graph) { | 659 bool Intrinsifier::Build_Float32x4ShuffleX(FlowGraph* flow_graph) { |
660 return BuildFloat32x4Shuffle(flow_graph, | 660 return BuildFloat32x4Shuffle(flow_graph, |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 Definition* backing_store = builder.AddDefinition( | 758 Definition* backing_store = builder.AddDefinition( |
759 new LoadFieldInstr(new Value(growable_array), | 759 new LoadFieldInstr(new Value(growable_array), |
760 GrowableObjectArray::data_offset(), | 760 GrowableObjectArray::data_offset(), |
761 Type::ZoneHandle(), | 761 Type::ZoneHandle(), |
762 builder.TokenPos())); | 762 builder.TokenPos())); |
763 Definition* result = builder.AddDefinition( | 763 Definition* result = builder.AddDefinition( |
764 new LoadIndexedInstr(new Value(backing_store), | 764 new LoadIndexedInstr(new Value(backing_store), |
765 new Value(index), | 765 new Value(index), |
766 Instance::ElementSizeFor(kArrayCid), // index scale | 766 Instance::ElementSizeFor(kArrayCid), // index scale |
767 kArrayCid, | 767 kArrayCid, |
768 Isolate::kNoDeoptId, | 768 Thread::kNoDeoptId, |
769 builder.TokenPos())); | 769 builder.TokenPos())); |
770 builder.AddIntrinsicReturn(new Value(result)); | 770 builder.AddIntrinsicReturn(new Value(result)); |
771 return true; | 771 return true; |
772 } | 772 } |
773 | 773 |
774 | 774 |
775 bool Intrinsifier::Build_GrowableArraySetIndexed(FlowGraph* flow_graph) { | 775 bool Intrinsifier::Build_GrowableArraySetIndexed(FlowGraph* flow_graph) { |
776 if (Isolate::Current()->flags().type_checks()) { | 776 if (Isolate::Current()->flags().type_checks()) { |
777 return false; | 777 return false; |
778 } | 778 } |
(...skipping 15 matching lines...) Expand all Loading... |
794 Type::ZoneHandle(), | 794 Type::ZoneHandle(), |
795 builder.TokenPos())); | 795 builder.TokenPos())); |
796 | 796 |
797 builder.AddInstruction( | 797 builder.AddInstruction( |
798 new StoreIndexedInstr(new Value(backing_store), | 798 new StoreIndexedInstr(new Value(backing_store), |
799 new Value(index), | 799 new Value(index), |
800 new Value(value), | 800 new Value(value), |
801 kEmitStoreBarrier, | 801 kEmitStoreBarrier, |
802 Instance::ElementSizeFor(kArrayCid), // index scale | 802 Instance::ElementSizeFor(kArrayCid), // index scale |
803 kArrayCid, | 803 kArrayCid, |
804 Isolate::kNoDeoptId, | 804 Thread::kNoDeoptId, |
805 builder.TokenPos())); | 805 builder.TokenPos())); |
806 // Return null. | 806 // Return null. |
807 Definition* null_def = builder.AddNullDefinition(); | 807 Definition* null_def = builder.AddNullDefinition(); |
808 builder.AddIntrinsicReturn(new Value(null_def)); | 808 builder.AddIntrinsicReturn(new Value(null_def)); |
809 return true; | 809 return true; |
810 } | 810 } |
811 | 811 |
812 | 812 |
813 bool Intrinsifier::Build_GrowableArraySetData(FlowGraph* flow_graph) { | 813 bool Intrinsifier::Build_GrowableArraySetData(FlowGraph* flow_graph) { |
814 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | 814 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
815 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 815 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
816 BlockBuilder builder(flow_graph, normal_entry); | 816 BlockBuilder builder(flow_graph, normal_entry); |
817 | 817 |
818 Definition* data = builder.AddParameter(1); | 818 Definition* data = builder.AddParameter(1); |
819 Definition* growable_array = builder.AddParameter(2); | 819 Definition* growable_array = builder.AddParameter(2); |
820 | 820 |
821 const ICData& value_check = ICData::ZoneHandle(ICData::New( | 821 const ICData& value_check = ICData::ZoneHandle(ICData::New( |
822 flow_graph->function(), | 822 flow_graph->function(), |
823 String::Handle(flow_graph->function().name()), | 823 String::Handle(flow_graph->function().name()), |
824 Object::empty_array(), // Dummy args. descr. | 824 Object::empty_array(), // Dummy args. descr. |
825 Isolate::kNoDeoptId, | 825 Thread::kNoDeoptId, |
826 1)); | 826 1)); |
827 value_check.AddReceiverCheck(kArrayCid, flow_graph->function()); | 827 value_check.AddReceiverCheck(kArrayCid, flow_graph->function()); |
828 builder.AddInstruction( | 828 builder.AddInstruction( |
829 new CheckClassInstr(new Value(data), | 829 new CheckClassInstr(new Value(data), |
830 Isolate::kNoDeoptId, | 830 Thread::kNoDeoptId, |
831 value_check, | 831 value_check, |
832 builder.TokenPos())); | 832 builder.TokenPos())); |
833 | 833 |
834 builder.AddInstruction( | 834 builder.AddInstruction( |
835 new StoreInstanceFieldInstr(GrowableObjectArray::data_offset(), | 835 new StoreInstanceFieldInstr(GrowableObjectArray::data_offset(), |
836 new Value(growable_array), | 836 new Value(growable_array), |
837 new Value(data), | 837 new Value(data), |
838 kEmitStoreBarrier, | 838 kEmitStoreBarrier, |
839 builder.TokenPos())); | 839 builder.TokenPos())); |
840 // Return null. | 840 // Return null. |
841 Definition* null_def = builder.AddNullDefinition(); | 841 Definition* null_def = builder.AddNullDefinition(); |
842 builder.AddIntrinsicReturn(new Value(null_def)); | 842 builder.AddIntrinsicReturn(new Value(null_def)); |
843 return true; | 843 return true; |
844 } | 844 } |
845 | 845 |
846 | 846 |
847 bool Intrinsifier::Build_GrowableArraySetLength(FlowGraph* flow_graph) { | 847 bool Intrinsifier::Build_GrowableArraySetLength(FlowGraph* flow_graph) { |
848 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); | 848 GraphEntryInstr* graph_entry = flow_graph->graph_entry(); |
849 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); | 849 TargetEntryInstr* normal_entry = graph_entry->normal_entry(); |
850 BlockBuilder builder(flow_graph, normal_entry); | 850 BlockBuilder builder(flow_graph, normal_entry); |
851 | 851 |
852 Definition* length = builder.AddParameter(1); | 852 Definition* length = builder.AddParameter(1); |
853 Definition* growable_array = builder.AddParameter(2); | 853 Definition* growable_array = builder.AddParameter(2); |
854 | 854 |
855 builder.AddInstruction( | 855 builder.AddInstruction( |
856 new CheckSmiInstr(new Value(length), | 856 new CheckSmiInstr(new Value(length), |
857 Isolate::kNoDeoptId, | 857 Thread::kNoDeoptId, |
858 builder.TokenPos())); | 858 builder.TokenPos())); |
859 builder.AddInstruction( | 859 builder.AddInstruction( |
860 new StoreInstanceFieldInstr(GrowableObjectArray::length_offset(), | 860 new StoreInstanceFieldInstr(GrowableObjectArray::length_offset(), |
861 new Value(growable_array), | 861 new Value(growable_array), |
862 new Value(length), | 862 new Value(length), |
863 kNoStoreBarrier, | 863 kNoStoreBarrier, |
864 builder.TokenPos())); | 864 builder.TokenPos())); |
865 Definition* null_def = builder.AddNullDefinition(); | 865 Definition* null_def = builder.AddNullDefinition(); |
866 builder.AddIntrinsicReturn(new Value(null_def)); | 866 builder.AddIntrinsicReturn(new Value(null_def)); |
867 return true; | 867 return true; |
868 } | 868 } |
869 | 869 |
870 } // namespace dart | 870 } // namespace dart |
OLD | NEW |