| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 spill_slot_count_ += 2; | 459 spill_slot_count_ += 2; |
| 460 } else { | 460 } else { |
| 461 spill_slot_count_++; | 461 spill_slot_count_++; |
| 462 } | 462 } |
| 463 } | 463 } |
| 464 iterator.Advance(); | 464 iterator.Advance(); |
| 465 } | 465 } |
| 466 } | 466 } |
| 467 | 467 |
| 468 | 468 |
| 469 LEnvironment* LChunkBuilderBase::CreateEnvironment( |
| 470 HEnvironment* hydrogen_env, |
| 471 int* argument_index_accumulator, |
| 472 ZoneList<HValue*>* objects_to_materialize) { |
| 473 if (hydrogen_env == NULL) return NULL; |
| 474 |
| 475 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer(), |
| 476 argument_index_accumulator, |
| 477 objects_to_materialize); |
| 478 BailoutId ast_id = hydrogen_env->ast_id(); |
| 479 ASSERT(!ast_id.IsNone() || |
| 480 hydrogen_env->frame_type() != JS_FUNCTION); |
| 481 int value_count = hydrogen_env->length() - hydrogen_env->specials_count(); |
| 482 LEnvironment* result = |
| 483 new(zone()) LEnvironment(hydrogen_env->closure(), |
| 484 hydrogen_env->frame_type(), |
| 485 ast_id, |
| 486 hydrogen_env->parameter_count(), |
| 487 argument_count_, |
| 488 value_count, |
| 489 outer, |
| 490 hydrogen_env->entry(), |
| 491 zone()); |
| 492 int argument_index = *argument_index_accumulator; |
| 493 |
| 494 // Store the environment description into the environment |
| 495 // (with holes for nested objects) |
| 496 for (int i = 0; i < hydrogen_env->length(); ++i) { |
| 497 if (hydrogen_env->is_special_index(i)) continue; |
| 498 |
| 499 LOperand* op; |
| 500 HValue* value = hydrogen_env->values()->at(i); |
| 501 if (value->IsArgumentsObject() || value->IsCapturedObject()) { |
| 502 op = LEnvironment::materialization_marker(); |
| 503 } else if (value->IsPushArgument()) { |
| 504 op = new(zone()) LArgument(argument_index++); |
| 505 } else { |
| 506 op = UseAny(value); |
| 507 } |
| 508 result->AddValue(op, |
| 509 value->representation(), |
| 510 value->CheckFlag(HInstruction::kUint32)); |
| 511 } |
| 512 |
| 513 // Recursively store the nested objects into the environment |
| 514 for (int i = 0; i < hydrogen_env->length(); ++i) { |
| 515 if (hydrogen_env->is_special_index(i)) continue; |
| 516 |
| 517 HValue* value = hydrogen_env->values()->at(i); |
| 518 if (value->IsArgumentsObject() || value->IsCapturedObject()) { |
| 519 AddObjectToMaterialize(value, objects_to_materialize, result); |
| 520 } |
| 521 } |
| 522 |
| 523 if (hydrogen_env->frame_type() == JS_FUNCTION) { |
| 524 *argument_index_accumulator = argument_index; |
| 525 } |
| 526 |
| 527 return result; |
| 528 } |
| 529 |
| 530 |
| 531 // Add an object to the supplied environment and object materialization list. |
| 532 // |
| 533 // Notes: |
| 534 // |
| 535 // We are building three lists here: |
| 536 // |
| 537 // 1. In the result->object_mapping_ list (added to by the |
| 538 // LEnvironment::Add*Object methods), we store the lengths (number |
| 539 // of fields) of the captured objects in depth-first traversal order, or |
| 540 // in case of duplicated objects, we store the index to the duplicate object |
| 541 // (with a tag to differentiate between captured and duplicated objects). |
| 542 // |
| 543 // 2. The object fields are stored in the result->values_ list |
| 544 // (added to by the LEnvironment.AddValue method) sequentially as lists |
| 545 // of fields with holes for nested objects (the holes will be expanded |
| 546 // later by LCodegen::AddToTranslation according to the |
| 547 // LEnvironment.object_mapping_ list). |
| 548 // |
| 549 // 3. The auxiliary objects_to_materialize array stores the hydrogen values |
| 550 // in the same order as result->object_mapping_ list. This is used |
| 551 // to detect duplicate values and calculate the corresponding object index. |
| 552 void LChunkBuilderBase::AddObjectToMaterialize(HValue* value, |
| 553 ZoneList<HValue*>* objects_to_materialize, LEnvironment* result) { |
| 554 int object_index = objects_to_materialize->length(); |
| 555 // Store the hydrogen value into the de-duplication array |
| 556 objects_to_materialize->Add(value, zone()); |
| 557 // Find out whether we are storing a duplicated value |
| 558 int previously_materialized_object = -1; |
| 559 for (int prev = 0; prev < object_index; ++prev) { |
| 560 if (objects_to_materialize->at(prev) == value) { |
| 561 previously_materialized_object = prev; |
| 562 break; |
| 563 } |
| 564 } |
| 565 // Store the captured object length (or duplicated object index) |
| 566 // into the environment. For duplicated objects, we stop here. |
| 567 int length = value->OperandCount(); |
| 568 bool is_arguments = value->IsArgumentsObject(); |
| 569 if (previously_materialized_object >= 0) { |
| 570 result->AddDuplicateObject(previously_materialized_object); |
| 571 return; |
| 572 } else { |
| 573 result->AddNewObject(is_arguments ? length - 1 : length, is_arguments); |
| 574 } |
| 575 // Store the captured object's fields into the environment |
| 576 for (int i = is_arguments ? 1 : 0; i < length; ++i) { |
| 577 LOperand* op; |
| 578 HValue* arg_value = value->OperandAt(i); |
| 579 if (arg_value->IsArgumentsObject() || arg_value->IsCapturedObject()) { |
| 580 // Insert a hole for nested objects |
| 581 op = LEnvironment::materialization_marker(); |
| 582 } else { |
| 583 ASSERT(!arg_value->IsPushArgument()); |
| 584 // For ordinary values, tell the register allocator we need the value |
| 585 // to be alive here |
| 586 op = UseAny(arg_value); |
| 587 } |
| 588 result->AddValue(op, |
| 589 arg_value->representation(), |
| 590 arg_value->CheckFlag(HInstruction::kUint32)); |
| 591 } |
| 592 // Recursively store all the nested captured objects into the environment |
| 593 for (int i = is_arguments ? 1 : 0; i < length; ++i) { |
| 594 HValue* arg_value = value->OperandAt(i); |
| 595 if (arg_value->IsArgumentsObject() || arg_value->IsCapturedObject()) { |
| 596 AddObjectToMaterialize(arg_value, objects_to_materialize, result); |
| 597 } |
| 598 } |
| 599 } |
| 600 |
| 601 |
| 469 LInstruction* LChunkBuilder::CheckElideControlInstruction( | 602 LInstruction* LChunkBuilder::CheckElideControlInstruction( |
| 470 HControlInstruction* instr) { | 603 HControlInstruction* instr) { |
| 471 HBasicBlock* successor; | 604 HBasicBlock* successor; |
| 472 if (!instr->KnownSuccessorBlock(&successor)) return NULL; | 605 if (!instr->KnownSuccessorBlock(&successor)) return NULL; |
| 473 return new(zone()) LGoto(successor); | 606 return new(zone()) LGoto(successor); |
| 474 } | 607 } |
| 475 | 608 |
| 476 | 609 |
| 477 LPhase::~LPhase() { | 610 LPhase::~LPhase() { |
| 478 if (ShouldProduceTraceOutput()) { | 611 if (ShouldProduceTraceOutput()) { |
| 479 isolate()->GetHTracer()->TraceLithium(name(), chunk_); | 612 isolate()->GetHTracer()->TraceLithium(name(), chunk_); |
| 480 } | 613 } |
| 481 } | 614 } |
| 482 | 615 |
| 483 | 616 |
| 484 } } // namespace v8::internal | 617 } } // namespace v8::internal |
| OLD | NEW |