| 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 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 | 283 |
| 284 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { | 284 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { |
| 285 stream->Add("if typeof "); | 285 stream->Add("if typeof "); |
| 286 value()->PrintTo(stream); | 286 value()->PrintTo(stream); |
| 287 stream->Add(" == \"%s\" then B%d else B%d", | 287 stream->Add(" == \"%s\" then B%d else B%d", |
| 288 *hydrogen()->type_literal()->ToCString(), | 288 *hydrogen()->type_literal()->ToCString(), |
| 289 true_block_id(), false_block_id()); | 289 true_block_id(), false_block_id()); |
| 290 } | 290 } |
| 291 | 291 |
| 292 | 292 |
| 293 void LStoreCodeEntry::PrintDataTo(StringStream* stream) { |
| 294 stream->Add(" = "); |
| 295 function()->PrintTo(stream); |
| 296 stream->Add(".code_entry = "); |
| 297 code_object()->PrintTo(stream); |
| 298 } |
| 299 |
| 300 |
| 293 void LInnerAllocatedObject::PrintDataTo(StringStream* stream) { | 301 void LInnerAllocatedObject::PrintDataTo(StringStream* stream) { |
| 294 stream->Add(" = "); | 302 stream->Add(" = "); |
| 295 base_object()->PrintTo(stream); | 303 base_object()->PrintTo(stream); |
| 296 stream->Add(" + %d", offset()); | 304 stream->Add(" + %d", offset()); |
| 297 } | 305 } |
| 298 | 306 |
| 299 | 307 |
| 300 void LCallConstantFunction::PrintDataTo(StringStream* stream) { | 308 void LCallConstantFunction::PrintDataTo(StringStream* stream) { |
| 301 stream->Add("#%d / ", arity()); | 309 stream->Add("#%d / ", arity()); |
| 302 } | 310 } |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 765 LOperand* right = NULL; | 773 LOperand* right = NULL; |
| 766 int constant_value = 0; | 774 int constant_value = 0; |
| 767 bool does_deopt = false; | 775 bool does_deopt = false; |
| 768 if (right_value->IsConstant()) { | 776 if (right_value->IsConstant()) { |
| 769 HConstant* constant = HConstant::cast(right_value); | 777 HConstant* constant = HConstant::cast(right_value); |
| 770 right = chunk_->DefineConstantOperand(constant); | 778 right = chunk_->DefineConstantOperand(constant); |
| 771 constant_value = constant->Integer32Value() & 0x1f; | 779 constant_value = constant->Integer32Value() & 0x1f; |
| 772 // Left shifts can deoptimize if we shift by > 0 and the result cannot be | 780 // Left shifts can deoptimize if we shift by > 0 and the result cannot be |
| 773 // truncated to smi. | 781 // truncated to smi. |
| 774 if (instr->representation().IsSmi() && constant_value > 0) { | 782 if (instr->representation().IsSmi() && constant_value > 0) { |
| 775 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { | 783 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi); |
| 776 if (!it.value()->CheckFlag(HValue::kTruncatingToSmi)) { | |
| 777 does_deopt = true; | |
| 778 break; | |
| 779 } | |
| 780 } | |
| 781 } | 784 } |
| 782 } else { | 785 } else { |
| 783 right = UseFixed(right_value, ecx); | 786 right = UseFixed(right_value, ecx); |
| 784 } | 787 } |
| 785 | 788 |
| 786 // Shift operations can only deoptimize if we do a logical shift by 0 and | 789 // Shift operations can only deoptimize if we do a logical shift by 0 and |
| 787 // the result cannot be truncated to int32. | 790 // the result cannot be truncated to int32. |
| 788 if (op == Token::SHR && constant_value == 0) { | 791 if (op == Token::SHR && constant_value == 0) { |
| 789 if (FLAG_opt_safe_uint32_operations) { | 792 if (FLAG_opt_safe_uint32_operations) { |
| 790 does_deopt = !instr->CheckFlag(HInstruction::kUint32); | 793 does_deopt = !instr->CheckFlag(HInstruction::kUint32); |
| 791 } else { | 794 } else { |
| 792 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) { | 795 does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32); |
| 793 if (!it.value()->CheckFlag(HValue::kTruncatingToInt32)) { | |
| 794 does_deopt = true; | |
| 795 break; | |
| 796 } | |
| 797 } | |
| 798 } | 796 } |
| 799 } | 797 } |
| 800 | 798 |
| 801 LInstruction* result = | 799 LInstruction* result = |
| 802 DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt)); | 800 DefineSameAsFirst(new(zone()) LShiftI(op, left, right, does_deopt)); |
| 803 return does_deopt ? AssignEnvironment(result) : result; | 801 return does_deopt ? AssignEnvironment(result) : result; |
| 804 } | 802 } |
| 805 | 803 |
| 806 | 804 |
| 807 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, | 805 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1153 } | 1151 } |
| 1154 | 1152 |
| 1155 | 1153 |
| 1156 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { | 1154 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { |
| 1157 ++argument_count_; | 1155 ++argument_count_; |
| 1158 LOperand* argument = UseAny(instr->argument()); | 1156 LOperand* argument = UseAny(instr->argument()); |
| 1159 return new(zone()) LPushArgument(argument); | 1157 return new(zone()) LPushArgument(argument); |
| 1160 } | 1158 } |
| 1161 | 1159 |
| 1162 | 1160 |
| 1161 LInstruction* LChunkBuilder::DoStoreCodeEntry( |
| 1162 HStoreCodeEntry* store_code_entry) { |
| 1163 LOperand* function = UseRegister(store_code_entry->function()); |
| 1164 LOperand* code_object = UseTempRegister(store_code_entry->code_object()); |
| 1165 return new(zone()) LStoreCodeEntry(function, code_object); |
| 1166 } |
| 1167 |
| 1168 |
| 1163 LInstruction* LChunkBuilder::DoInnerAllocatedObject( | 1169 LInstruction* LChunkBuilder::DoInnerAllocatedObject( |
| 1164 HInnerAllocatedObject* inner_object) { | 1170 HInnerAllocatedObject* inner_object) { |
| 1165 LOperand* base_object = UseRegisterAtStart(inner_object->base_object()); | 1171 LOperand* base_object = UseRegisterAtStart(inner_object->base_object()); |
| 1166 LInnerAllocatedObject* result = | 1172 LInnerAllocatedObject* result = |
| 1167 new(zone()) LInnerAllocatedObject(base_object); | 1173 new(zone()) LInnerAllocatedObject(base_object); |
| 1168 return DefineAsRegister(result); | 1174 return DefineAsRegister(result); |
| 1169 } | 1175 } |
| 1170 | 1176 |
| 1171 | 1177 |
| 1172 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) { | 1178 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) { |
| (...skipping 1394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2567 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { | 2573 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { |
| 2568 // There are no real uses of the arguments object. | 2574 // There are no real uses of the arguments object. |
| 2569 // arguments.length and element access are supported directly on | 2575 // arguments.length and element access are supported directly on |
| 2570 // stack arguments, and any real arguments object use causes a bailout. | 2576 // stack arguments, and any real arguments object use causes a bailout. |
| 2571 // So this value is never used. | 2577 // So this value is never used. |
| 2572 return NULL; | 2578 return NULL; |
| 2573 } | 2579 } |
| 2574 | 2580 |
| 2575 | 2581 |
| 2576 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) { | 2582 LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) { |
| 2583 instr->ReplayEnvironment(current_block_->last_environment()); |
| 2584 |
| 2577 // There are no real uses of a captured object. | 2585 // There are no real uses of a captured object. |
| 2578 return NULL; | 2586 return NULL; |
| 2579 } | 2587 } |
| 2580 | 2588 |
| 2581 | 2589 |
| 2582 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { | 2590 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { |
| 2583 info()->MarkAsRequiresFrame(); | 2591 info()->MarkAsRequiresFrame(); |
| 2584 LOperand* args = UseRegister(instr->arguments()); | 2592 LOperand* args = UseRegister(instr->arguments()); |
| 2585 LOperand* length; | 2593 LOperand* length; |
| 2586 LOperand* index; | 2594 LOperand* index; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2615 } | 2623 } |
| 2616 | 2624 |
| 2617 | 2625 |
| 2618 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( | 2626 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch( |
| 2619 HIsConstructCallAndBranch* instr) { | 2627 HIsConstructCallAndBranch* instr) { |
| 2620 return new(zone()) LIsConstructCallAndBranch(TempRegister()); | 2628 return new(zone()) LIsConstructCallAndBranch(TempRegister()); |
| 2621 } | 2629 } |
| 2622 | 2630 |
| 2623 | 2631 |
| 2624 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { | 2632 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { |
| 2625 HEnvironment* env = current_block_->last_environment(); | 2633 instr->ReplayEnvironment(current_block_->last_environment()); |
| 2626 ASSERT(env != NULL); | |
| 2627 | |
| 2628 env->set_ast_id(instr->ast_id()); | |
| 2629 | |
| 2630 env->Drop(instr->pop_count()); | |
| 2631 for (int i = instr->values()->length() - 1; i >= 0; --i) { | |
| 2632 HValue* value = instr->values()->at(i); | |
| 2633 if (instr->HasAssignedIndexAt(i)) { | |
| 2634 env->Bind(instr->GetAssignedIndexAt(i), value); | |
| 2635 } else { | |
| 2636 env->Push(value); | |
| 2637 } | |
| 2638 } | |
| 2639 | 2634 |
| 2640 // If there is an instruction pending deoptimization environment create a | 2635 // If there is an instruction pending deoptimization environment create a |
| 2641 // lazy bailout instruction to capture the environment. | 2636 // lazy bailout instruction to capture the environment. |
| 2642 if (!pending_deoptimization_ast_id_.IsNone()) { | 2637 if (!pending_deoptimization_ast_id_.IsNone()) { |
| 2643 ASSERT(pending_deoptimization_ast_id_ == instr->ast_id()); | 2638 ASSERT(pending_deoptimization_ast_id_ == instr->ast_id()); |
| 2644 LLazyBailout* lazy_bailout = new(zone()) LLazyBailout; | 2639 LLazyBailout* lazy_bailout = new(zone()) LLazyBailout; |
| 2645 LInstruction* result = AssignEnvironment(lazy_bailout); | 2640 LInstruction* result = AssignEnvironment(lazy_bailout); |
| 2646 // Store the lazy deopt environment with the instruction if needed. Right | 2641 // Store the lazy deopt environment with the instruction if needed. Right |
| 2647 // now it is only used for LInstanceOfKnownGlobal. | 2642 // now it is only used for LInstanceOfKnownGlobal. |
| 2648 instruction_pending_deoptimization_environment_-> | 2643 instruction_pending_deoptimization_environment_-> |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2733 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2728 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
| 2734 LOperand* object = UseRegister(instr->object()); | 2729 LOperand* object = UseRegister(instr->object()); |
| 2735 LOperand* index = UseTempRegister(instr->index()); | 2730 LOperand* index = UseTempRegister(instr->index()); |
| 2736 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); | 2731 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); |
| 2737 } | 2732 } |
| 2738 | 2733 |
| 2739 | 2734 |
| 2740 } } // namespace v8::internal | 2735 } } // namespace v8::internal |
| 2741 | 2736 |
| 2742 #endif // V8_TARGET_ARCH_IA32 | 2737 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |