30 #if defined(V8_TARGET_ARCH_IA32)
39 #define DEFINE_COMPILE(type) \
40 void L##type::CompileToNative(LCodeGen* generator) { \
41 generator->Do##type(this); \
48 register_spills_[i] =
NULL;
51 double_register_spills_[i] =
NULL;
57 LOperand* spill_operand) {
58 ASSERT(spill_operand->IsStackSlot());
59 ASSERT(register_spills_[allocation_index] ==
NULL);
60 register_spills_[allocation_index] = spill_operand;
65 LOperand* spill_operand) {
66 ASSERT(spill_operand->IsDoubleStackSlot());
67 ASSERT(double_register_spills_[allocation_index] ==
NULL);
68 double_register_spills_[allocation_index] = spill_operand;
73 void LInstruction::VerifyCall() {
81 for (UseIterator it(
this); !it.Done(); it.Advance()) {
83 ASSERT(operand->HasFixedPolicy() ||
84 operand->IsUsedAtStart());
88 ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy());
95 stream->Add(
"%s ", this->
Mnemonic());
115 for (
int i = 0; i < InputCount(); i++) {
116 if (i > 0) stream->Add(
" ");
131 stream->Add(
" Dead block replaced with B%d", rep->block_id());
137 for (
int i = 0; i < 4; i++) {
138 if (parallel_moves_[i] !=
NULL && !parallel_moves_[i]->
IsRedundant()) {
148 for (
int i = 0; i < 4; i++) {
150 if (parallel_moves_[i] !=
NULL) {
164 case Token::MOD:
return "mod-d";
177 case Token::MOD:
return "mod-t";
179 case Token::BIT_AND:
return "bit-and-t";
180 case Token::BIT_OR:
return "bit-or-t";
181 case Token::BIT_XOR:
return "bit-xor-t";
182 case Token::SHL:
return "sal-t";
183 case Token::SAR:
return "sar-t";
184 case Token::SHR:
return "shr-t";
222 stream->Add(
"if is_object(");
229 stream->Add(
"if is_string(");
236 stream->Add(
"if is_smi(");
243 stream->Add(
"if is_undetectable(");
250 stream->Add(
"if string_compare(");
258 stream->Add(
"if has_instance_type(");
265 stream->Add(
"if has_cached_array_index(");
272 stream->Add(
"if class_of_test(");
274 stream->Add(
", \"%o\") then B%d else B%d",
275 *hydrogen()->class_name(),
282 stream->Add(
"if typeof ");
284 stream->Add(
" == \"%s\" then B%d else B%d",
291 stream->Add(
"#%d / ",
arity());
296 stream->Add(
"/%s ", hydrogen()->OpName());
302 stream->Add(
"/pow_half ");
325 stream->Add(
" #%d / ",
arity());
330 stream->Add(
"[ecx] #%d / ",
arity());
335 SmartArrayPointer<char> name_string =
name()->ToCString();
336 stream->Add(
"%s #%d / ", *name_string,
arity());
341 SmartArrayPointer<char> name_string =
name()->ToCString();
342 stream->Add(
"%s #%d / ", *name_string,
arity());
347 stream->Add(
"#%d / ",
arity());
356 stream->Add(
" #%d / ",
arity());
363 stream->Add(
" length ");
366 stream->Add(
" index ");
414 stream->Add(
"] <- ");
423 stream->Add(
"] <- ");
432 stream->Add(
"] <- ");
443 LPlatformChunk* LChunkBuilder::Build() {
445 chunk_ =
new(zone()) LPlatformChunk(info(), graph());
446 HPhase phase(
"L_Building chunk", chunk_);
450 int alignment_state_index = chunk_->GetNextSpillIndex(
false);
452 USE(alignment_state_index);
454 const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
455 for (
int i = 0; i < blocks->length(); i++) {
456 HBasicBlock* next =
NULL;
457 if (i < blocks->length() - 1) next = blocks->at(i + 1);
458 DoBasicBlock(blocks->at(i), next);
459 if (is_aborted())
return NULL;
466 void LChunkBuilder::Abort(
const char* reason) {
467 info()->set_bailout_reason(reason);
472 LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
478 LUnallocated* LChunkBuilder::ToUnallocated(XMMRegister reg) {
484 LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) {
485 return Use(value, ToUnallocated(fixed_register));
489 LOperand* LChunkBuilder::UseFixedDouble(HValue* value, XMMRegister reg) {
490 return Use(value, ToUnallocated(reg));
494 LOperand* LChunkBuilder::UseRegister(HValue* value) {
499 LOperand* LChunkBuilder::UseRegisterAtStart(HValue* value) {
506 LOperand* LChunkBuilder::UseTempRegister(HValue* value) {
511 LOperand* LChunkBuilder::Use(HValue* value) {
516 LOperand* LChunkBuilder::UseAtStart(HValue* value) {
522 LOperand* LChunkBuilder::UseOrConstant(HValue* value) {
523 return value->IsConstant()
529 LOperand* LChunkBuilder::UseOrConstantAtStart(HValue* value) {
530 return value->IsConstant()
536 LOperand* LChunkBuilder::UseRegisterOrConstant(HValue* value) {
537 return value->IsConstant()
539 : UseRegister(value);
543 LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) {
544 return value->IsConstant()
546 : UseRegisterAtStart(value);
550 LOperand* LChunkBuilder::UseAny(HValue* value) {
551 return value->IsConstant()
557 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) {
558 if (value->EmitAtUses()) {
560 VisitInstruction(instr);
562 operand->set_virtual_register(value->id());
567 template<
int I,
int T>
568 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1, I, T>* instr,
569 LUnallocated* result) {
570 result->set_virtual_register(current_instruction_->id());
571 instr->set_result(result);
576 template<
int I,
int T>
577 LInstruction* LChunkBuilder::DefineAsRegister(
578 LTemplateInstruction<1, I, T>* instr) {
584 template<
int I,
int T>
585 LInstruction* LChunkBuilder::DefineAsSpilled(
586 LTemplateInstruction<1, I, T>* instr,
593 template<
int I,
int T>
594 LInstruction* LChunkBuilder::DefineSameAsFirst(
595 LTemplateInstruction<1, I, T>* instr) {
601 template<
int I,
int T>
602 LInstruction* LChunkBuilder::DefineFixed(LTemplateInstruction<1, I, T>* instr,
604 return Define(instr, ToUnallocated(reg));
608 template<
int I,
int T>
609 LInstruction* LChunkBuilder::DefineFixedDouble(
610 LTemplateInstruction<1, I, T>* instr,
612 return Define(instr, ToUnallocated(reg));
616 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
617 HEnvironment* hydrogen_env = current_block_->last_environment();
618 int argument_index_accumulator = 0;
619 instr->set_environment(CreateEnvironment(hydrogen_env,
620 &argument_index_accumulator));
625 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
626 HInstruction* hinstr,
627 CanDeoptimize can_deoptimize) {
632 instr = AssignPointerMap(instr);
634 if (hinstr->HasObservableSideEffects()) {
635 ASSERT(hinstr->next()->IsSimulate());
637 ASSERT(instruction_pending_deoptimization_environment_ ==
NULL);
638 ASSERT(pending_deoptimization_ast_id_.IsNone());
639 instruction_pending_deoptimization_environment_ = instr;
640 pending_deoptimization_ast_id_ = sim->ast_id();
647 bool needs_environment =
648 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) ||
649 !hinstr->HasObservableSideEffects();
650 if (needs_environment && !instr->HasEnvironment()) {
651 instr = AssignEnvironment(instr);
658 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
659 ASSERT(!instr->HasPointerMap());
660 instr->set_pointer_map(
new(zone()) LPointerMap(position_, zone()));
665 LUnallocated* LChunkBuilder::TempRegister() {
666 LUnallocated* operand =
668 operand->set_virtual_register(allocator_->GetVirtualRegister());
669 if (!allocator_->AllocationOk()) {
670 Abort(
"Not enough virtual registers (temps).");
676 LOperand* LChunkBuilder::FixedTemp(Register reg) {
677 LUnallocated* operand = ToUnallocated(reg);
678 ASSERT(operand->HasFixedPolicy());
683 LOperand* LChunkBuilder::FixedTemp(XMMRegister reg) {
684 LUnallocated* operand = ToUnallocated(reg);
685 ASSERT(operand->HasFixedPolicy());
690 LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
691 return new(zone()) LLabel(instr->block());
695 LInstruction* LChunkBuilder::DoSoftDeoptimize(HSoftDeoptimize* instr) {
696 return AssignEnvironment(
new(zone()) LDeoptimize);
700 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
701 return AssignEnvironment(
new(zone()) LDeoptimize);
706 HBitwiseBinaryOperation* instr) {
707 if (instr->representation().IsTagged()) {
708 ASSERT(instr->left()->representation().IsTagged());
709 ASSERT(instr->right()->representation().IsTagged());
711 LOperand* context = UseFixed(instr->context(),
esi);
712 LOperand* left = UseFixed(instr->left(),
edx);
713 LOperand* right = UseFixed(instr->right(),
eax);
714 LArithmeticT* result =
new(zone()) LArithmeticT(op, context, left, right);
715 return MarkAsCall(DefineFixed(result,
eax), instr);
718 ASSERT(instr->representation().IsInteger32());
719 ASSERT(instr->left()->representation().IsInteger32());
720 ASSERT(instr->right()->representation().IsInteger32());
721 LOperand* left = UseRegisterAtStart(instr->left());
723 HValue* right_value = instr->right();
724 LOperand* right =
NULL;
725 int constant_value = 0;
726 if (right_value->IsConstant()) {
728 right = chunk_->DefineConstantOperand(constant);
729 constant_value = constant->Integer32Value() & 0x1f;
731 right = UseFixed(right_value,
ecx);
736 bool does_deopt =
false;
737 if (op == Token::SHR && constant_value == 0) {
738 if (FLAG_opt_safe_uint32_operations) {
741 for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
750 LInstruction* result =
751 DefineSameAsFirst(
new(zone()) LShiftI(op, left, right, does_deopt));
752 return does_deopt ? AssignEnvironment(result) : result;
756 LInstruction* LChunkBuilder::DoArithmeticD(
Token::Value op,
757 HArithmeticBinaryOperation* instr) {
758 ASSERT(instr->representation().IsDouble());
759 ASSERT(instr->left()->representation().IsDouble());
760 ASSERT(instr->right()->representation().IsDouble());
762 LOperand* left = UseRegisterAtStart(instr->left());
763 LOperand* right = UseRegisterAtStart(instr->right());
764 LArithmeticD* result =
new(zone()) LArithmeticD(op, left, right);
765 return DefineSameAsFirst(result);
769 LInstruction* LChunkBuilder::DoArithmeticT(
Token::Value op,
770 HArithmeticBinaryOperation* instr) {
776 HValue* left = instr->left();
777 HValue* right = instr->right();
778 ASSERT(left->representation().IsTagged());
779 ASSERT(right->representation().IsTagged());
780 LOperand* context = UseFixed(instr->context(),
esi);
781 LOperand* left_operand = UseFixed(left,
edx);
782 LOperand* right_operand = UseFixed(right,
eax);
783 LArithmeticT* result =
784 new(zone()) LArithmeticT(op, context, left_operand, right_operand);
785 return MarkAsCall(DefineFixed(result,
eax), instr);
789 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
791 current_block_ = block;
792 next_block_ = next_block;
793 if (block->IsStartBlock()) {
794 block->UpdateEnvironment(graph_->start_environment());
796 }
else if (block->predecessors()->length() == 1) {
799 ASSERT(block->phis()->length() == 0);
800 HBasicBlock* pred = block->predecessors()->at(0);
801 HEnvironment* last_environment = pred->last_environment();
804 if (pred->end()->SecondSuccessor() ==
NULL) {
805 ASSERT(pred->end()->FirstSuccessor() == block);
807 if (pred->end()->FirstSuccessor()->block_id() > block->block_id() ||
808 pred->end()->SecondSuccessor()->block_id() > block->block_id()) {
809 last_environment = last_environment->Copy();
812 block->UpdateEnvironment(last_environment);
813 ASSERT(pred->argument_count() >= 0);
814 argument_count_ = pred->argument_count();
817 HBasicBlock* pred = block->predecessors()->at(0);
819 HEnvironment* last_environment = pred->last_environment();
820 for (
int i = 0; i < block->phis()->length(); ++i) {
821 HPhi* phi = block->phis()->at(i);
822 last_environment->SetValueAt(phi->merged_index(), phi);
824 for (
int i = 0; i < block->deleted_phis()->length(); ++i) {
825 last_environment->SetValueAt(block->deleted_phis()->at(i),
826 graph_->GetConstantUndefined());
828 block->UpdateEnvironment(last_environment);
830 argument_count_ = pred->argument_count();
832 HInstruction* current = block->first();
833 int start = chunk_->instructions()->length();
834 while (current !=
NULL && !is_aborted()) {
836 if (!current->EmitAtUses()) {
837 VisitInstruction(current);
839 current = current->next();
841 int end = chunk_->instructions()->length() - 1;
843 block->set_first_instruction_index(start);
844 block->set_last_instruction_index(end);
846 block->set_argument_count(argument_count_);
848 current_block_ =
NULL;
852 void LChunkBuilder::VisitInstruction(HInstruction* current) {
853 HInstruction* old_current = current_instruction_;
854 current_instruction_ = current;
855 if (current->has_position()) position_ = current->position();
856 LInstruction* instr = current->CompileToLithium(
this);
859 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
860 instr = AssignPointerMap(instr);
862 if (FLAG_stress_environments && !instr->HasEnvironment()) {
863 instr = AssignEnvironment(instr);
865 instr->set_hydrogen_value(current);
866 chunk_->AddInstruction(instr, current_block_);
868 current_instruction_ = old_current;
872 LEnvironment* LChunkBuilder::CreateEnvironment(
873 HEnvironment* hydrogen_env,
874 int* argument_index_accumulator) {
875 if (hydrogen_env ==
NULL)
return NULL;
877 LEnvironment* outer =
878 CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator);
879 BailoutId ast_id = hydrogen_env->ast_id();
880 ASSERT(!ast_id.IsNone() ||
882 int value_count = hydrogen_env->length();
883 LEnvironment* result =
884 new(zone()) LEnvironment(hydrogen_env->closure(),
885 hydrogen_env->frame_type(),
887 hydrogen_env->parameter_count(),
891 hydrogen_env->entry(),
893 int argument_index = *argument_index_accumulator;
894 for (
int i = 0; i < value_count; ++i) {
895 if (hydrogen_env->is_special_index(i))
continue;
897 HValue* value = hydrogen_env->values()->at(i);
899 if (value->IsArgumentsObject()) {
901 }
else if (value->IsPushArgument()) {
902 op =
new(zone()) LArgument(argument_index++);
907 value->representation(),
912 *argument_index_accumulator = argument_index;
919 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
920 return new(zone()) LGoto(instr->FirstSuccessor()->block_id());
924 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
925 HValue* value = instr->value();
926 if (value->EmitAtUses()) {
927 ASSERT(value->IsConstant());
928 ASSERT(!value->representation().IsDouble());
930 ? instr->FirstSuccessor()
931 : instr->SecondSuccessor();
932 return new(zone()) LGoto(successor->block_id());
938 HType type = value->type();
939 if (!rep.IsTagged() || type.IsSmi() || type.IsBoolean()) {
940 return new(zone()) LBranch(UseRegister(value),
NULL);
943 ToBooleanStub::Types expected = instr->expected_input_types();
947 bool needs_temp = expected.NeedsMap() || expected.IsEmpty();
948 LOperand* temp = needs_temp ? TempRegister() :
NULL;
949 return AssignEnvironment(
new(zone()) LBranch(UseRegister(value), temp));
953 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
954 ASSERT(instr->value()->representation().IsTagged());
955 LOperand* value = UseRegisterAtStart(instr->value());
956 return new(zone()) LCmpMapAndBranch(value);
960 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) {
961 return DefineAsRegister(
new(zone()) LArgumentsLength(Use(length->value())));
965 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
966 return DefineAsRegister(
new(zone()) LArgumentsElements);
970 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
973 LOperand* context = UseFixed(instr->context(),
esi);
974 LInstanceOf* result =
new(zone()) LInstanceOf(context, left, right);
975 return MarkAsCall(DefineFixed(result,
eax), instr);
979 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
980 HInstanceOfKnownGlobal* instr) {
981 LInstanceOfKnownGlobal* result =
982 new(zone()) LInstanceOfKnownGlobal(
983 UseFixed(instr->context(),
esi),
986 return MarkAsCall(DefineFixed(result,
eax), instr);
990 LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
991 LOperand* receiver = UseRegister(instr->receiver());
992 LOperand*
function = UseRegisterAtStart(instr->function());
993 LOperand* temp = TempRegister();
994 LWrapReceiver* result =
995 new(zone()) LWrapReceiver(receiver,
function, temp);
996 return AssignEnvironment(DefineSameAsFirst(result));
1000 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1001 LOperand*
function = UseFixed(instr->function(),
edi);
1002 LOperand* receiver = UseFixed(instr->receiver(),
eax);
1003 LOperand* length = UseFixed(instr->length(),
ebx);
1004 LOperand* elements = UseFixed(instr->elements(),
ecx);
1005 LApplyArguments* result =
new(zone()) LApplyArguments(
function,
1009 return MarkAsCall(DefineFixed(result,
eax), instr, CAN_DEOPTIMIZE_EAGERLY);
1013 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1015 LOperand* argument = UseAny(instr->argument());
1016 return new(zone()) LPushArgument(argument);
1020 LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
1021 return instr->HasNoUses()
1023 : DefineAsRegister(
new(zone()) LThisFunction);
1027 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1028 return instr->HasNoUses() ?
NULL : DefineAsRegister(
new(zone()) LContext);
1032 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
1033 LOperand* context = UseRegisterAtStart(instr->value());
1034 return DefineAsRegister(
new(zone()) LOuterContext(context));
1038 LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
1039 LOperand* context = UseFixed(instr->context(),
esi);
1040 return MarkAsCall(
new(zone()) LDeclareGlobals(context), instr);
1044 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
1045 LOperand* context = UseRegisterAtStart(instr->value());
1046 return DefineAsRegister(
new(zone()) LGlobalObject(context));
1050 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) {
1051 LOperand* global_object = UseRegisterAtStart(instr->value());
1052 return DefineAsRegister(
new(zone()) LGlobalReceiver(global_object));
1056 LInstruction* LChunkBuilder::DoCallConstantFunction(
1057 HCallConstantFunction* instr) {
1058 argument_count_ -= instr->argument_count();
1059 return MarkAsCall(DefineFixed(
new(zone()) LCallConstantFunction,
eax), instr);
1063 LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
1064 LOperand* context = UseFixed(instr->context(),
esi);
1065 LOperand*
function = UseFixed(instr->function(),
edi);
1066 argument_count_ -= instr->argument_count();
1067 LInvokeFunction* result =
new(zone()) LInvokeFunction(context,
function);
1068 return MarkAsCall(DefineFixed(result,
eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
1072 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1074 if (op == kMathLog) {
1075 ASSERT(instr->representation().IsDouble());
1076 ASSERT(instr->value()->representation().IsDouble());
1077 LOperand* context = UseAny(instr->context());
1078 LOperand* input = UseRegisterAtStart(instr->value());
1079 LUnaryMathOperation* result =
new(zone()) LUnaryMathOperation(context,
1081 return DefineSameAsFirst(result);
1082 }
else if (op == kMathSin || op == kMathCos || op == kMathTan) {
1083 LOperand* context = UseFixed(instr->context(),
esi);
1084 LOperand* input = UseFixedDouble(instr->value(),
xmm1);
1085 LUnaryMathOperation* result =
new(zone()) LUnaryMathOperation(context,
1087 return MarkAsCall(DefineFixedDouble(result,
xmm1), instr);
1089 LOperand* input = UseRegisterAtStart(instr->value());
1090 LOperand* context = UseAny(instr->context());
1092 LOperand* temp = TempRegister();
1093 LMathPowHalf* result =
new(zone()) LMathPowHalf(context, input, temp);
1094 return DefineSameAsFirst(result);
1096 LUnaryMathOperation* result =
new(zone()) LUnaryMathOperation(context,
1100 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1102 return AssignEnvironment(DefineAsRegister(result));
1104 return AssignEnvironment(DefineAsRegister(result));
1106 return DefineSameAsFirst(result);
1115 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
1116 ASSERT(instr->key()->representation().IsTagged());
1117 LOperand* context = UseFixed(instr->context(),
esi);
1118 LOperand* key = UseFixed(instr->key(),
ecx);
1119 argument_count_ -= instr->argument_count();
1120 LCallKeyed* result =
new(zone()) LCallKeyed(context, key);
1121 return MarkAsCall(DefineFixed(result,
eax), instr);
1125 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) {
1126 LOperand* context = UseFixed(instr->context(),
esi);
1127 argument_count_ -= instr->argument_count();
1128 LCallNamed* result =
new(zone()) LCallNamed(context);
1129 return MarkAsCall(DefineFixed(result,
eax), instr);
1133 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) {
1134 LOperand* context = UseFixed(instr->context(),
esi);
1135 argument_count_ -= instr->argument_count();
1136 LCallGlobal* result =
new(zone()) LCallGlobal(context);
1137 return MarkAsCall(DefineFixed(result,
eax), instr);
1141 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) {
1142 argument_count_ -= instr->argument_count();
1143 return MarkAsCall(DefineFixed(
new(zone()) LCallKnownGlobal,
eax), instr);
1147 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1148 LOperand* context = UseFixed(instr->context(),
esi);
1149 LOperand* constructor = UseFixed(instr->constructor(),
edi);
1150 argument_count_ -= instr->argument_count();
1151 LCallNew* result =
new(zone()) LCallNew(context, constructor);
1152 return MarkAsCall(DefineFixed(result,
eax), instr);
1156 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1157 LOperand* context = UseFixed(instr->context(),
esi);
1158 LOperand*
function = UseFixed(instr->function(),
edi);
1159 argument_count_ -= instr->argument_count();
1160 LCallFunction* result =
new(zone()) LCallFunction(context,
function);
1161 return MarkAsCall(DefineFixed(result,
eax), instr);
1165 LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
1166 argument_count_ -= instr->argument_count();
1167 LOperand* context = UseFixed(instr->context(),
esi);
1168 return MarkAsCall(DefineFixed(
new(zone()) LCallRuntime(context),
eax), instr);
1172 LInstruction* LChunkBuilder::DoShr(HShr* instr) {
1173 return DoShift(Token::SHR, instr);
1177 LInstruction* LChunkBuilder::DoSar(HSar* instr) {
1178 return DoShift(Token::SAR, instr);
1182 LInstruction* LChunkBuilder::DoShl(HShl* instr) {
1183 return DoShift(Token::SHL, instr);
1187 LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
1188 if (instr->representation().IsInteger32()) {
1189 ASSERT(instr->left()->representation().IsInteger32());
1190 ASSERT(instr->right()->representation().IsInteger32());
1192 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
1193 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
1194 return DefineSameAsFirst(
new(zone()) LBitI(left, right));
1196 ASSERT(instr->representation().IsTagged());
1197 ASSERT(instr->left()->representation().IsTagged());
1198 ASSERT(instr->right()->representation().IsTagged());
1200 LOperand* context = UseFixed(instr->context(),
esi);
1201 LOperand* left = UseFixed(instr->left(),
edx);
1202 LOperand* right = UseFixed(instr->right(),
eax);
1203 LArithmeticT* result =
1204 new(zone()) LArithmeticT(instr->op(), context, left, right);
1205 return MarkAsCall(DefineFixed(result,
eax), instr);
1210 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) {
1211 ASSERT(instr->value()->representation().IsInteger32());
1212 ASSERT(instr->representation().IsInteger32());
1213 if (instr->HasNoUses())
return NULL;
1214 LOperand* input = UseRegisterAtStart(instr->value());
1215 LBitNotI* result =
new(zone()) LBitNotI(input);
1216 return DefineSameAsFirst(result);
1220 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1221 if (instr->representation().IsDouble()) {
1223 }
else if (instr->representation().IsInteger32()) {
1226 LOperand* temp = FixedTemp(
edx);
1227 LOperand* dividend = UseFixed(instr->left(),
eax);
1228 LOperand* divisor = UseRegister(instr->right());
1229 LDivI* result =
new(zone()) LDivI(dividend, divisor, temp);
1230 return AssignEnvironment(DefineFixed(result,
eax));
1232 ASSERT(instr->representation().IsTagged());
1238 HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue* dividend) {
1240 if (dividend->representation().IsInteger32()) {
1243 }
else if (dividend->IsChange() &&
1251 HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) {
1252 if (divisor->IsConstant() &&
1256 divisor->block()->zone());
1262 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
1263 HValue* right = instr->right();
1265 LOperand* divisor = chunk_->DefineConstantOperand(
HConstant::cast(right));
1267 if (divisor_si == 0) {
1268 LOperand* dividend = UseRegister(instr->left());
1269 return AssignEnvironment(DefineAsRegister(
1270 new(zone()) LMathFloorOfDiv(dividend, divisor,
NULL)));
1273 LOperand* dividend = divisor_si < -1 ? UseTempRegister(instr->left()) :
1274 UseRegisterAtStart(instr->left());
1275 LInstruction* result = DefineAsRegister(
1276 new(zone()) LMathFloorOfDiv(dividend, divisor,
NULL));
1277 return divisor_si < 0 ? AssignEnvironment(result) : result;
1280 LOperand* dividend = UseFixed(instr->left(),
eax);
1281 LOperand* temp = TempRegister();
1282 LInstruction* result = DefineFixed(
1283 new(zone()) LMathFloorOfDiv(dividend, divisor, temp),
edx);
1284 return divisor_si < 0 ? AssignEnvironment(result) : result;
1289 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1290 if (instr->representation().IsInteger32()) {
1291 ASSERT(instr->left()->representation().IsInteger32());
1292 ASSERT(instr->right()->representation().IsInteger32());
1294 LInstruction* result;
1295 if (instr->HasPowerOf2Divisor()) {
1297 LOperand* value = UseRegisterAtStart(instr->left());
1299 new(zone()) LModI(value, UseOrConstant(instr->right()),
NULL);
1300 result = DefineSameAsFirst(mod);
1304 LOperand* temp = FixedTemp(
edx);
1305 LOperand* value = UseFixed(instr->left(),
eax);
1306 LOperand* divisor = UseRegister(instr->right());
1307 LModI* mod =
new(zone()) LModI(value, divisor, temp);
1308 result = DefineFixed(mod,
edx);
1313 ? AssignEnvironment(result)
1315 }
else if (instr->representation().IsTagged()) {
1316 return DoArithmeticT(Token::MOD, instr);
1318 ASSERT(instr->representation().IsDouble());
1322 LOperand* left = UseFixedDouble(instr->left(),
xmm2);
1323 LOperand* right = UseFixedDouble(instr->right(),
xmm1);
1324 LArithmeticD* result =
new(zone()) LArithmeticD(Token::MOD, left, right);
1325 return MarkAsCall(DefineFixedDouble(result,
xmm1), instr);
1330 LInstruction* LChunkBuilder::DoMul(HMul* instr) {
1331 if (instr->representation().IsInteger32()) {
1332 ASSERT(instr->left()->representation().IsInteger32());
1333 ASSERT(instr->right()->representation().IsInteger32());
1334 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
1335 LOperand* right = UseOrConstant(instr->MostConstantOperand());
1336 LOperand* temp =
NULL;
1338 temp = TempRegister();
1340 LMulI* mul =
new(zone()) LMulI(left, right, temp);
1343 AssignEnvironment(mul);
1345 return DefineSameAsFirst(mul);
1346 }
else if (instr->representation().IsDouble()) {
1349 ASSERT(instr->representation().IsTagged());
1355 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1356 if (instr->representation().IsInteger32()) {
1357 ASSERT(instr->left()->representation().IsInteger32());
1358 ASSERT(instr->right()->representation().IsInteger32());
1359 LOperand* left = UseRegisterAtStart(instr->left());
1360 LOperand* right = UseOrConstantAtStart(instr->right());
1361 LSubI* sub =
new(zone()) LSubI(left, right);
1362 LInstruction* result = DefineSameAsFirst(sub);
1364 result = AssignEnvironment(result);
1367 }
else if (instr->representation().IsDouble()) {
1370 ASSERT(instr->representation().IsTagged());
1376 LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
1377 if (instr->representation().IsInteger32()) {
1378 ASSERT(instr->left()->representation().IsInteger32());
1379 ASSERT(instr->right()->representation().IsInteger32());
1380 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
1381 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
1382 LAddI* add =
new(zone()) LAddI(left, right);
1383 LInstruction* result = DefineSameAsFirst(add);
1385 result = AssignEnvironment(result);
1388 }
else if (instr->representation().IsDouble()) {
1391 ASSERT(instr->representation().IsTagged());
1397 LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
1398 LOperand* left =
NULL;
1399 LOperand* right =
NULL;
1400 if (instr->representation().IsInteger32()) {
1401 ASSERT(instr->left()->representation().IsInteger32());
1402 ASSERT(instr->right()->representation().IsInteger32());
1403 left = UseRegisterAtStart(instr->LeastConstantOperand());
1404 right = UseOrConstantAtStart(instr->MostConstantOperand());
1406 ASSERT(instr->representation().IsDouble());
1407 ASSERT(instr->left()->representation().IsDouble());
1408 ASSERT(instr->right()->representation().IsDouble());
1409 left = UseRegisterAtStart(instr->left());
1410 right = UseRegisterAtStart(instr->right());
1412 LMathMinMax* minmax =
new(zone()) LMathMinMax(left, right);
1413 return DefineSameAsFirst(minmax);
1417 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1418 ASSERT(instr->representation().IsDouble());
1421 Representation exponent_type = instr->right()->representation();
1422 ASSERT(instr->left()->representation().IsDouble());
1423 LOperand* left = UseFixedDouble(instr->left(),
xmm2);
1424 LOperand* right = exponent_type.IsDouble() ?
1425 UseFixedDouble(instr->right(),
xmm1) :
1426 UseFixed(instr->right(),
eax);
1427 LPower* result =
new(zone()) LPower(left, right);
1428 return MarkAsCall(DefineFixedDouble(result,
xmm3), instr,
1429 CAN_DEOPTIMIZE_EAGERLY);
1433 LInstruction* LChunkBuilder::DoRandom(HRandom* instr) {
1434 ASSERT(instr->representation().IsDouble());
1435 ASSERT(instr->global_object()->representation().IsTagged());
1436 LOperand* global_object = UseFixed(instr->global_object(),
eax);
1437 LRandom* result =
new(zone()) LRandom(global_object);
1438 return MarkAsCall(DefineFixedDouble(result,
xmm1), instr);
1442 LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
1443 ASSERT(instr->left()->representation().IsTagged());
1444 ASSERT(instr->right()->representation().IsTagged());
1445 LOperand* context = UseFixed(instr->context(),
esi);
1446 LOperand* left = UseFixed(instr->left(),
edx);
1447 LOperand* right = UseFixed(instr->right(),
eax);
1448 LCmpT* result =
new(zone()) LCmpT(context, left, right);
1449 return MarkAsCall(DefineFixed(result,
eax), instr);
1453 LInstruction* LChunkBuilder::DoCompareIDAndBranch(
1454 HCompareIDAndBranch* instr) {
1455 Representation r = instr->GetInputRepresentation();
1456 if (r.IsInteger32()) {
1457 ASSERT(instr->left()->representation().IsInteger32());
1458 ASSERT(instr->right()->representation().IsInteger32());
1459 LOperand* left = UseRegisterOrConstantAtStart(instr->left());
1460 LOperand* right = UseOrConstantAtStart(instr->right());
1461 return new(zone()) LCmpIDAndBranch(left, right);
1464 ASSERT(instr->left()->representation().IsDouble());
1465 ASSERT(instr->right()->representation().IsDouble());
1468 if (instr->left()->IsConstant() && instr->right()->IsConstant()) {
1469 left = UseRegisterOrConstantAtStart(instr->left());
1470 right = UseRegisterOrConstantAtStart(instr->right());
1472 left = UseRegisterAtStart(instr->left());
1473 right = UseRegisterAtStart(instr->right());
1475 return new(zone()) LCmpIDAndBranch(left, right);
1480 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
1481 HCompareObjectEqAndBranch* instr) {
1482 LOperand* left = UseRegisterAtStart(instr->left());
1483 LOperand* right = UseAtStart(instr->right());
1484 return new(zone()) LCmpObjectEqAndBranch(left, right);
1488 LInstruction* LChunkBuilder::DoCompareConstantEqAndBranch(
1489 HCompareConstantEqAndBranch* instr) {
1490 return new(zone()) LCmpConstantEqAndBranch(
1491 UseRegisterAtStart(instr->value()));
1495 LInstruction* LChunkBuilder::DoIsNilAndBranch(HIsNilAndBranch* instr) {
1498 return new(zone()) LIsNilAndBranch(UseRegisterAtStart(instr->value()), temp);
1502 LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
1503 ASSERT(instr->value()->representation().IsTagged());
1504 LOperand* temp = TempRegister();
1505 return new(zone()) LIsObjectAndBranch(UseRegister(instr->value()), temp);
1509 LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
1510 ASSERT(instr->value()->representation().IsTagged());
1511 LOperand* temp = TempRegister();
1512 return new(zone()) LIsStringAndBranch(UseRegister(instr->value()), temp);
1516 LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
1517 ASSERT(instr->value()->representation().IsTagged());
1518 return new(zone()) LIsSmiAndBranch(Use(instr->value()));
1522 LInstruction* LChunkBuilder::DoIsUndetectableAndBranch(
1523 HIsUndetectableAndBranch* instr) {
1524 ASSERT(instr ->value()->representation().IsTagged());
1525 return new(zone()) LIsUndetectableAndBranch(
1526 UseRegisterAtStart(instr->value()), TempRegister());
1530 LInstruction* LChunkBuilder::DoStringCompareAndBranch(
1531 HStringCompareAndBranch* instr) {
1532 ASSERT(instr->left()->representation().IsTagged());
1533 ASSERT(instr->right()->representation().IsTagged());
1534 LOperand* context = UseFixed(instr->context(),
esi);
1535 LOperand* left = UseFixed(instr->left(),
edx);
1536 LOperand* right = UseFixed(instr->right(),
eax);
1538 LStringCompareAndBranch* result =
new(zone())
1539 LStringCompareAndBranch(context, left, right);
1541 return MarkAsCall(result, instr);
1545 LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch(
1546 HHasInstanceTypeAndBranch* instr) {
1547 ASSERT(instr->value()->representation().IsTagged());
1548 return new(zone()) LHasInstanceTypeAndBranch(
1549 UseRegisterAtStart(instr->value()),
1554 LInstruction* LChunkBuilder::DoGetCachedArrayIndex(
1555 HGetCachedArrayIndex* instr) {
1556 ASSERT(instr->value()->representation().IsTagged());
1557 LOperand* value = UseRegisterAtStart(instr->value());
1559 return DefineAsRegister(
new(zone()) LGetCachedArrayIndex(value));
1563 LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch(
1564 HHasCachedArrayIndexAndBranch* instr) {
1565 ASSERT(instr->value()->representation().IsTagged());
1566 return new(zone()) LHasCachedArrayIndexAndBranch(
1567 UseRegisterAtStart(instr->value()));
1571 LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
1572 HClassOfTestAndBranch* instr) {
1573 ASSERT(instr->value()->representation().IsTagged());
1574 return new(zone()) LClassOfTestAndBranch(UseRegister(instr->value()),
1580 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
1581 LOperand* array = UseRegisterAtStart(instr->value());
1582 return DefineAsRegister(
new(zone()) LJSArrayLength(array));
1586 LInstruction* LChunkBuilder::DoFixedArrayBaseLength(
1587 HFixedArrayBaseLength* instr) {
1588 LOperand* array = UseRegisterAtStart(instr->value());
1589 return DefineAsRegister(
new(zone()) LFixedArrayBaseLength(array));
1593 LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
1594 LOperand* map = UseRegisterAtStart(instr->value());
1595 return DefineAsRegister(
new(zone()) LMapEnumLength(map));
1599 LInstruction* LChunkBuilder::DoElementsKind(HElementsKind* instr) {
1600 LOperand*
object = UseRegisterAtStart(instr->value());
1601 return DefineAsRegister(
new(zone()) LElementsKind(
object));
1605 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
1606 LOperand*
object = UseRegister(instr->value());
1607 LValueOf* result =
new(zone()) LValueOf(
object, TempRegister());
1608 return DefineSameAsFirst(result);
1612 LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
1613 LOperand* date = UseFixed(instr->value(),
eax);
1614 LDateField* result =
1615 new(zone()) LDateField(date, FixedTemp(
ecx), instr->index());
1616 return MarkAsCall(DefineFixed(result,
eax), instr, CAN_DEOPTIMIZE_EAGERLY);
1620 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1621 return AssignEnvironment(
new(zone()) LBoundsCheck(
1622 UseRegisterOrConstantAtStart(instr->index()),
1623 UseAtStart(instr->length())));
1627 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1634 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
1635 LOperand* context = UseFixed(instr->context(),
esi);
1636 LOperand* value = UseFixed(instr->value(),
eax);
1637 return MarkAsCall(
new(zone()) LThrow(context, value), instr);
1641 LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) {
1646 LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
1654 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1655 Representation from = instr->from();
1656 Representation to = instr->to();
1657 if (from.IsTagged()) {
1658 if (to.IsDouble()) {
1659 LOperand* value = UseRegister(instr->value());
1661 LOperand* temp = instr->deoptimize_on_minus_zero()
1664 LNumberUntagD* res =
new(zone()) LNumberUntagD(value, temp);
1665 return AssignEnvironment(DefineAsRegister(res));
1667 ASSERT(to.IsInteger32());
1668 LOperand* value = UseRegister(instr->value());
1669 if (instr->value()->type().IsSmi()) {
1670 return DefineSameAsFirst(
new(zone()) LSmiUntag(value,
false));
1672 bool truncating = instr->CanTruncateToInt32();
1673 LOperand* xmm_temp =
1677 LTaggedToI* res =
new(zone()) LTaggedToI(value, xmm_temp);
1678 return AssignEnvironment(DefineSameAsFirst(res));
1681 }
else if (from.IsDouble()) {
1682 if (to.IsTagged()) {
1683 LOperand* value = UseRegister(instr->value());
1684 LOperand* temp = TempRegister();
1687 LUnallocated* result_temp = TempRegister();
1688 LNumberTagD* result =
new(zone()) LNumberTagD(value, temp);
1689 return AssignPointerMap(Define(result, result_temp));
1691 ASSERT(to.IsInteger32());
1692 bool truncating = instr->CanTruncateToInt32();
1694 LOperand* value = needs_temp ?
1695 UseTempRegister(instr->value()) : UseRegister(instr->value());
1696 LOperand* temp = needs_temp ? TempRegister() :
NULL;
1697 return AssignEnvironment(
1698 DefineAsRegister(
new(zone()) LDoubleToI(value, temp)));
1700 }
else if (from.IsInteger32()) {
1701 if (to.IsTagged()) {
1702 HValue* val = instr->value();
1703 LOperand* value = UseRegister(val);
1704 if (val->HasRange() && val->range()->IsInSmiRange()) {
1705 return DefineSameAsFirst(
new(zone()) LSmiTag(value));
1707 LOperand* temp = FixedTemp(
xmm1);
1708 LNumberTagU* result =
new(zone()) LNumberTagU(value, temp);
1709 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1711 LNumberTagI* result =
new(zone()) LNumberTagI(value);
1712 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1717 LOperand* temp = FixedTemp(
xmm1);
1718 return DefineAsRegister(
1719 new(zone()) LUint32ToDouble(UseRegister(instr->value()), temp));
1721 return DefineAsRegister(
1722 new(zone()) LInteger32ToDouble(Use(instr->value())));
1731 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) {
1732 LOperand* value = UseAtStart(instr->value());
1733 return AssignEnvironment(
new(zone()) LCheckNonSmi(value));
1737 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
1738 LOperand* value = UseRegisterAtStart(instr->value());
1739 LOperand* temp = TempRegister();
1740 LCheckInstanceType* result =
new(zone()) LCheckInstanceType(value, temp);
1741 return AssignEnvironment(result);
1745 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) {
1746 LOperand* temp = TempRegister();
1747 LCheckPrototypeMaps* result =
new(zone()) LCheckPrototypeMaps(temp);
1748 return AssignEnvironment(result);
1752 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
1753 LOperand* value = UseAtStart(instr->value());
1754 return AssignEnvironment(
new(zone()) LCheckSmi(value));
1758 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
1763 LOperand* value = Isolate::Current()->heap()->InNewSpace(*instr->target())
1764 ? UseRegisterAtStart(instr->value())
1765 : UseAtStart(instr->value());
1766 return AssignEnvironment(
new(zone()) LCheckFunction(value));
1770 LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
1771 LOperand* value = UseRegisterAtStart(instr->value());
1772 LCheckMaps* result =
new(zone()) LCheckMaps(value);
1773 return AssignEnvironment(result);
1777 LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
1778 HValue* value = instr->value();
1779 Representation input_rep = value->representation();
1780 if (input_rep.IsDouble()) {
1781 LOperand* reg = UseRegister(value);
1782 return DefineFixed(
new(zone()) LClampDToUint8(reg),
eax);
1783 }
else if (input_rep.IsInteger32()) {
1784 LOperand* reg = UseFixed(value,
eax);
1785 return DefineFixed(
new(zone()) LClampIToUint8(reg),
eax);
1787 ASSERT(input_rep.IsTagged());
1788 LOperand* reg = UseFixed(value,
eax);
1791 LOperand* temp = FixedTemp(
xmm1);
1792 LClampTToUint8* result =
new(zone()) LClampTToUint8(reg, temp);
1793 return AssignEnvironment(DefineFixed(result,
eax));
1798 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
1799 return new(zone()) LReturn(UseFixed(instr->value(),
eax));
1803 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1804 Representation r = instr->representation();
1805 if (r.IsInteger32()) {
1806 return DefineAsRegister(
new(zone()) LConstantI);
1807 }
else if (r.IsDouble()) {
1808 double value = instr->DoubleValue();
1809 LOperand* temp = (BitCast<uint64_t, double>(value) != 0)
1812 return DefineAsRegister(
new(zone()) LConstantD(temp));
1813 }
else if (r.IsTagged()) {
1814 return DefineAsRegister(
new(zone()) LConstantT);
1822 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
1823 LLoadGlobalCell* result =
new(zone()) LLoadGlobalCell;
1824 return instr->RequiresHoleCheck()
1825 ? AssignEnvironment(DefineAsRegister(result))
1826 : DefineAsRegister(result);
1830 LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
1831 LOperand* context = UseFixed(instr->context(),
esi);
1832 LOperand* global_object = UseFixed(instr->global_object(),
edx);
1833 LLoadGlobalGeneric* result =
1834 new(zone()) LLoadGlobalGeneric(context, global_object);
1835 return MarkAsCall(DefineFixed(result,
eax), instr);
1839 LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
1840 LStoreGlobalCell* result =
1841 new(zone()) LStoreGlobalCell(UseRegister(instr->value()));
1842 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
1846 LInstruction* LChunkBuilder::DoStoreGlobalGeneric(HStoreGlobalGeneric* instr) {
1847 LOperand* context = UseFixed(instr->context(),
esi);
1848 LOperand* global_object = UseFixed(instr->global_object(),
edx);
1849 LOperand* value = UseFixed(instr->value(),
eax);
1850 LStoreGlobalGeneric* result =
1851 new(zone()) LStoreGlobalGeneric(context, global_object, value);
1852 return MarkAsCall(result, instr);
1856 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
1857 LOperand* context = UseRegisterAtStart(instr->value());
1858 LInstruction* result =
1859 DefineAsRegister(
new(zone()) LLoadContextSlot(context));
1860 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
1864 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
1867 LOperand* context = UseRegister(instr->context());
1868 if (instr->NeedsWriteBarrier()) {
1869 value = UseTempRegister(instr->value());
1870 temp = TempRegister();
1872 value = UseRegister(instr->value());
1875 LInstruction* result =
new(zone()) LStoreContextSlot(context, value, temp);
1876 return instr->RequiresHoleCheck() ? AssignEnvironment(result) : result;
1880 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
1881 ASSERT(instr->representation().IsTagged());
1882 LOperand* obj = UseRegisterAtStart(instr->object());
1883 return DefineAsRegister(
new(zone()) LLoadNamedField(obj));
1887 LInstruction* LChunkBuilder::DoLoadNamedFieldPolymorphic(
1888 HLoadNamedFieldPolymorphic* instr) {
1889 ASSERT(instr->representation().IsTagged());
1890 if (instr->need_generic()) {
1891 LOperand* context = UseFixed(instr->context(),
esi);
1892 LOperand* obj = UseFixed(instr->object(),
edx);
1893 LLoadNamedFieldPolymorphic* result =
1894 new(zone()) LLoadNamedFieldPolymorphic(context, obj);
1895 return MarkAsCall(DefineFixed(result,
eax), instr);
1897 LOperand* context = UseAny(instr->context());
1898 LOperand* obj = UseRegisterAtStart(instr->object());
1899 LLoadNamedFieldPolymorphic* result =
1900 new(zone()) LLoadNamedFieldPolymorphic(context, obj);
1901 return AssignEnvironment(DefineAsRegister(result));
1906 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
1907 LOperand* context = UseFixed(instr->context(),
esi);
1908 LOperand*
object = UseFixed(instr->object(),
edx);
1909 LLoadNamedGeneric* result =
new(zone()) LLoadNamedGeneric(context,
object);
1910 return MarkAsCall(DefineFixed(result,
eax), instr);
1914 LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
1915 HLoadFunctionPrototype* instr) {
1916 return AssignEnvironment(DefineAsRegister(
1917 new(zone()) LLoadFunctionPrototype(UseRegister(instr->function()),
1922 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) {
1923 LOperand* input = UseRegisterAtStart(instr->value());
1924 return DefineAsRegister(
new(zone()) LLoadElements(input));
1928 LInstruction* LChunkBuilder::DoLoadExternalArrayPointer(
1929 HLoadExternalArrayPointer* instr) {
1930 LOperand* input = UseRegisterAtStart(instr->value());
1931 return DefineAsRegister(
new(zone()) LLoadExternalArrayPointer(input));
1935 LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
1936 HLoadKeyedFastElement* instr) {
1937 ASSERT(instr->representation().IsTagged());
1938 ASSERT(instr->key()->representation().IsInteger32() ||
1939 instr->key()->representation().IsTagged());
1940 LOperand* obj = UseRegisterAtStart(instr->object());
1941 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
1942 LLoadKeyedFastElement* result =
new(zone()) LLoadKeyedFastElement(obj, key);
1943 if (instr->RequiresHoleCheck()) AssignEnvironment(result);
1944 return DefineAsRegister(result);
1948 LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
1949 HLoadKeyedFastDoubleElement* instr) {
1950 ASSERT(instr->representation().IsDouble());
1951 ASSERT(instr->key()->representation().IsInteger32() ||
1952 instr->key()->representation().IsTagged());
1953 LOperand* elements = UseRegisterAtStart(instr->elements());
1954 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
1955 LLoadKeyedFastDoubleElement* result =
1956 new(zone()) LLoadKeyedFastDoubleElement(elements, key);
1957 return AssignEnvironment(DefineAsRegister(result));
1961 LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
1962 HLoadKeyedSpecializedArrayElement* instr) {
1965 (instr->representation().IsInteger32() &&
1968 (instr->representation().IsDouble() &&
1971 ASSERT(instr->key()->representation().IsInteger32() ||
1972 instr->key()->representation().IsTagged());
1973 LOperand* external_pointer = UseRegister(instr->external_pointer());
1974 bool clobbers_key = ExternalArrayOpRequiresTemp(
1975 instr->key()->representation(), elements_kind);
1976 LOperand* key = clobbers_key
1977 ? UseTempRegister(instr->key())
1978 : UseRegisterOrConstant(instr->key());
1980 LLoadKeyedSpecializedArrayElement* result =
1981 new(zone()) LLoadKeyedSpecializedArrayElement(external_pointer, key);
1982 LInstruction* load_instr = DefineAsRegister(result);
1986 ? AssignEnvironment(load_instr)
1991 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
1992 LOperand* context = UseFixed(instr->context(),
esi);
1993 LOperand*
object = UseFixed(instr->object(),
edx);
1994 LOperand* key = UseFixed(instr->key(),
ecx);
1996 LLoadKeyedGeneric* result =
1997 new(zone()) LLoadKeyedGeneric(context,
object, key);
1998 return MarkAsCall(DefineFixed(result,
eax), instr);
2002 LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
2003 HStoreKeyedFastElement* instr) {
2004 bool needs_write_barrier = instr->NeedsWriteBarrier();
2005 ASSERT(instr->value()->representation().IsTagged());
2006 ASSERT(instr->object()->representation().IsTagged());
2007 ASSERT(instr->key()->representation().IsInteger32() ||
2008 instr->key()->representation().IsTagged());
2010 LOperand* obj = UseRegister(instr->object());
2011 LOperand* val = needs_write_barrier
2012 ? UseTempRegister(instr->value())
2013 : UseRegisterAtStart(instr->value());
2014 LOperand* key = needs_write_barrier
2015 ? UseTempRegister(instr->key())
2016 : UseRegisterOrConstantAtStart(instr->key());
2017 return new(zone()) LStoreKeyedFastElement(obj, key, val);
2021 LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
2022 HStoreKeyedFastDoubleElement* instr) {
2023 ASSERT(instr->value()->representation().IsDouble());
2024 ASSERT(instr->elements()->representation().IsTagged());
2025 ASSERT(instr->key()->representation().IsInteger32() ||
2026 instr->key()->representation().IsTagged());
2028 LOperand* elements = UseRegisterAtStart(instr->elements());
2029 LOperand* val = UseTempRegister(instr->value());
2030 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2032 return new(zone()) LStoreKeyedFastDoubleElement(elements, key, val);
2036 LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
2037 HStoreKeyedSpecializedArrayElement* instr) {
2040 (instr->value()->representation().IsInteger32() &&
2043 (instr->value()->representation().IsDouble() &&
2046 ASSERT(instr->external_pointer()->representation().IsExternal());
2047 ASSERT(instr->key()->representation().IsInteger32() ||
2048 instr->key()->representation().IsTagged());
2050 LOperand* external_pointer = UseRegister(instr->external_pointer());
2051 LOperand* val =
NULL;
2056 val = UseFixed(instr->value(),
eax);
2058 val = UseRegister(instr->value());
2060 bool clobbers_key = ExternalArrayOpRequiresTemp(
2061 instr->key()->representation(), elements_kind);
2062 LOperand* key = clobbers_key
2063 ? UseTempRegister(instr->key())
2064 : UseRegisterOrConstant(instr->key());
2065 return new(zone()) LStoreKeyedSpecializedArrayElement(external_pointer,
2071 LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
2072 LOperand* context = UseFixed(instr->context(),
esi);
2073 LOperand*
object = UseFixed(instr->object(),
edx);
2074 LOperand* key = UseFixed(instr->key(),
ecx);
2075 LOperand* value = UseFixed(instr->value(),
eax);
2077 ASSERT(instr->object()->representation().IsTagged());
2078 ASSERT(instr->key()->representation().IsTagged());
2079 ASSERT(instr->value()->representation().IsTagged());
2081 LStoreKeyedGeneric* result =
2082 new(zone()) LStoreKeyedGeneric(context,
object, key, value);
2083 return MarkAsCall(result, instr);
2087 LInstruction* LChunkBuilder::DoTransitionElementsKind(
2088 HTransitionElementsKind* instr) {
2089 ElementsKind from_kind = instr->original_map()->elements_kind();
2090 ElementsKind to_kind = instr->transitioned_map()->elements_kind();
2092 LOperand*
object = UseRegister(instr->object());
2093 LOperand* new_map_reg = TempRegister();
2094 LOperand* temp_reg = TempRegister();
2095 LTransitionElementsKind* result =
2096 new(zone()) LTransitionElementsKind(
object, new_map_reg, temp_reg);
2097 return DefineSameAsFirst(result);
2099 LOperand*
object = UseFixed(instr->object(),
eax);
2100 LOperand* fixed_object_reg = FixedTemp(
edx);
2101 LOperand* new_map_reg = FixedTemp(
ebx);
2102 LTransitionElementsKind* result =
2103 new(zone()) LTransitionElementsKind(
object,
2106 return MarkAsCall(DefineFixed(result,
eax), instr);
2111 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
2112 bool needs_write_barrier = instr->NeedsWriteBarrier();
2113 bool needs_write_barrier_for_map = !instr->transition().is_null() &&
2114 instr->NeedsWriteBarrierForMap();
2117 if (needs_write_barrier) {
2118 obj = instr->is_in_object()
2119 ? UseRegister(instr->object())
2120 : UseTempRegister(instr->object());
2122 obj = needs_write_barrier_for_map
2123 ? UseRegister(instr->object())
2124 : UseRegisterAtStart(instr->object());
2127 LOperand* val = needs_write_barrier
2128 ? UseTempRegister(instr->value())
2129 : UseRegister(instr->value());
2133 LOperand* temp = (!instr->is_in_object() || needs_write_barrier ||
2134 needs_write_barrier_for_map) ? TempRegister() :
NULL;
2137 LOperand* temp_map = needs_write_barrier_for_map ? TempRegister() :
NULL;
2139 return new(zone()) LStoreNamedField(obj, val, temp, temp_map);
2143 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
2144 LOperand* context = UseFixed(instr->context(),
esi);
2145 LOperand*
object = UseFixed(instr->object(),
edx);
2146 LOperand* value = UseFixed(instr->value(),
eax);
2148 LStoreNamedGeneric* result =
2149 new(zone()) LStoreNamedGeneric(context,
object, value);
2150 return MarkAsCall(result, instr);
2154 LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) {
2155 LOperand* context = UseFixed(instr->context(),
esi);
2156 LOperand* left = UseOrConstantAtStart(instr->left());
2157 LOperand* right = UseOrConstantAtStart(instr->right());
2158 LStringAdd* string_add =
new(zone()) LStringAdd(context, left, right);
2159 return MarkAsCall(DefineFixed(string_add,
eax), instr);
2163 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
2164 LOperand*
string = UseTempRegister(instr->string());
2165 LOperand* index = UseTempRegister(instr->index());
2166 LOperand* context = UseAny(instr->context());
2167 LStringCharCodeAt* result =
2168 new(zone()) LStringCharCodeAt(context,
string, index);
2169 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
2173 LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
2174 LOperand* char_code = UseRegister(instr->value());
2175 LOperand* context = UseAny(instr->context());
2176 LStringCharFromCode* result =
2177 new(zone()) LStringCharFromCode(context, char_code);
2178 return AssignPointerMap(DefineAsRegister(result));
2182 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
2183 LOperand*
string = UseRegisterAtStart(instr->value());
2184 return DefineAsRegister(
new(zone()) LStringLength(
string));
2188 LInstruction* LChunkBuilder::DoAllocateObject(HAllocateObject* instr) {
2189 LOperand* context = UseFixed(instr->context(),
esi);
2190 LOperand* temp = TempRegister();
2191 LAllocateObject* result =
new(zone()) LAllocateObject(context, temp);
2192 return AssignPointerMap(DefineAsRegister(result));
2196 LInstruction* LChunkBuilder::DoFastLiteral(HFastLiteral* instr) {
2197 LOperand* context = UseFixed(instr->context(),
esi);
2199 DefineFixed(
new(zone()) LFastLiteral(context),
eax), instr);
2203 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
2204 LOperand* context = UseFixed(instr->context(),
esi);
2206 DefineFixed(
new(zone()) LArrayLiteral(context),
eax), instr);
2210 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) {
2211 LOperand* context = UseFixed(instr->context(),
esi);
2213 DefineFixed(
new(zone()) LObjectLiteral(context),
eax), instr);
2217 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
2218 LOperand* context = UseFixed(instr->context(),
esi);
2220 DefineFixed(
new(zone()) LRegExpLiteral(context),
eax), instr);
2224 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
2225 LOperand* context = UseFixed(instr->context(),
esi);
2227 DefineFixed(
new(zone()) LFunctionLiteral(context),
eax), instr);
2231 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
2232 LOperand* context = UseFixed(instr->context(),
esi);
2233 LOperand*
object = UseAtStart(instr->object());
2234 LOperand* key = UseOrConstantAtStart(instr->key());
2235 LDeleteProperty* result =
new(zone()) LDeleteProperty(context,
object, key);
2236 return MarkAsCall(DefineFixed(result,
eax), instr);
2240 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
2241 ASSERT(argument_count_ == 0);
2242 allocator_->MarkAsOsrEntry();
2243 current_block_->last_environment()->set_ast_id(instr->ast_id());
2244 return AssignEnvironment(
new(zone()) LOsrEntry);
2248 LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
2249 int spill_index = chunk()->GetParameterStackSlot(instr->index());
2250 return DefineAsSpilled(
new(zone()) LParameter, spill_index);
2254 LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
2255 int spill_index = chunk()->GetNextSpillIndex(
false);
2257 Abort(
"Too many spill slots needed for OSR");
2260 return DefineAsSpilled(
new(zone()) LUnknownOSRValue, spill_index);
2264 LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
2265 LOperand* context = UseFixed(instr->context(),
esi);
2266 argument_count_ -= instr->argument_count();
2267 LCallStub* result =
new(zone()) LCallStub(context);
2268 return MarkAsCall(DefineFixed(result,
eax), instr);
2272 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
2281 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
2282 LOperand* args = UseRegister(instr->arguments());
2283 LOperand* length = UseTempRegister(instr->length());
2284 LOperand* index = Use(instr->index());
2285 return DefineAsRegister(
new(zone()) LAccessArgumentsAt(args, length, index));
2289 LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
2290 LOperand*
object = UseFixed(instr->value(),
eax);
2291 LToFastProperties* result =
new(zone()) LToFastProperties(
object);
2292 return MarkAsCall(DefineFixed(result,
eax), instr);
2296 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2297 LOperand* context = UseFixed(instr->context(),
esi);
2298 LOperand* value = UseAtStart(instr->value());
2299 LTypeof* result =
new(zone()) LTypeof(context, value);
2300 return MarkAsCall(DefineFixed(result,
eax), instr);
2304 LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
2305 return new(zone()) LTypeofIsAndBranch(UseTempRegister(instr->value()));
2309 LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
2310 HIsConstructCallAndBranch* instr) {
2311 return new(zone()) LIsConstructCallAndBranch(TempRegister());
2315 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2316 HEnvironment* env = current_block_->last_environment();
2319 env->set_ast_id(instr->ast_id());
2321 env->Drop(instr->pop_count());
2322 for (
int i = 0; i < instr->values()->length(); ++i) {
2323 HValue* value = instr->values()->at(i);
2324 if (instr->HasAssignedIndexAt(i)) {
2325 env->Bind(instr->GetAssignedIndexAt(i), value);
2333 if (!pending_deoptimization_ast_id_.IsNone()) {
2334 ASSERT(pending_deoptimization_ast_id_ == instr->ast_id());
2335 LLazyBailout* lazy_bailout =
new(zone()) LLazyBailout;
2336 LInstruction* result = AssignEnvironment(lazy_bailout);
2339 instruction_pending_deoptimization_environment_->
2340 SetDeferredLazyDeoptimizationEnvironment(result->environment());
2341 instruction_pending_deoptimization_environment_ =
NULL;
2350 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
2351 if (instr->is_function_entry()) {
2352 LOperand* context = UseFixed(instr->context(),
esi);
2353 return MarkAsCall(
new(zone()) LStackCheck(context), instr);
2355 ASSERT(instr->is_backwards_branch());
2356 LOperand* context = UseAny(instr->context());
2357 return AssignEnvironment(
2358 AssignPointerMap(
new(zone()) LStackCheck(context)));
2363 LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
2364 HEnvironment* outer = current_block_->last_environment();
2365 HConstant* undefined = graph()->GetConstantUndefined();
2366 HEnvironment* inner = outer->CopyForInlining(instr->closure(),
2367 instr->arguments_count(),
2371 instr->inlining_kind());
2372 if (instr->arguments_var() !=
NULL) {
2373 inner->Bind(instr->arguments_var(), graph()->GetArgumentsObject());
2375 inner->set_entry(instr);
2376 current_block_->UpdateEnvironment(inner);
2377 chunk_->AddInlinedClosure(instr->closure());
2382 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2383 LInstruction* pop =
NULL;
2385 HEnvironment* env = current_block_->last_environment();
2387 if (env->entry()->arguments_pushed()) {
2388 int argument_count = env->arguments_environment()->parameter_count();
2389 pop =
new(zone()) LDrop(argument_count);
2390 argument_count_ -= argument_count;
2393 HEnvironment* outer = current_block_->last_environment()->
2394 DiscardInlined(
false);
2395 current_block_->UpdateEnvironment(outer);
2400 LInstruction* LChunkBuilder::DoIn(HIn* instr) {
2401 LOperand* context = UseFixed(instr->context(),
esi);
2402 LOperand* key = UseOrConstantAtStart(instr->key());
2403 LOperand*
object = UseOrConstantAtStart(instr->object());
2404 LIn* result =
new(zone()) LIn(context, key,
object);
2405 return MarkAsCall(DefineFixed(result,
eax), instr);
2409 LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) {
2410 LOperand* context = UseFixed(instr->context(),
esi);
2411 LOperand*
object = UseFixed(instr->enumerable(),
eax);
2412 LForInPrepareMap* result =
new(zone()) LForInPrepareMap(context,
object);
2413 return MarkAsCall(DefineFixed(result,
eax), instr, CAN_DEOPTIMIZE_EAGERLY);
2417 LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) {
2418 LOperand* map = UseRegister(instr->map());
2419 return AssignEnvironment(DefineAsRegister(
2420 new(zone()) LForInCacheArray(map)));
2424 LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
2425 LOperand* value = UseRegisterAtStart(instr->value());
2426 LOperand* map = UseRegisterAtStart(instr->map());
2427 return AssignEnvironment(
new(zone()) LCheckMapValue(value, map));
2431 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2432 LOperand*
object = UseRegister(instr->object());
2433 LOperand* index = UseTempRegister(instr->index());
2434 return DefineSameAsFirst(
new(zone()) LLoadFieldByIndex(
object, index));
2440 #endif // V8_TARGET_ARCH_IA32
#define DEFINE_COMPILE(type)
static LUnallocated * cast(LOperand *op)
friend class TempIterator
Handle< Map > transitioned_map()
virtual void PrintDataTo(StringStream *stream)
virtual void PrintDataTo(StringStream *stream)
Handle< Object > name() const
const char * ToCString(const v8::String::Utf8Value &value)
static String * cast(Object *obj)
virtual void PrintOutputOperandTo(StringStream *stream)
void MarkSpilledDoubleRegister(int allocation_index, LOperand *spill_operand)
virtual void PrintDataTo(StringStream *stream)
virtual void PrintDataTo(StringStream *stream)
static Representation Integer32()
LLabel(HBasicBlock *block)
Handle< String > name() const
static const int kNumAllocatableRegisters
static bool IsSupported(CpuFeature f)
Handle< Object > name() const
LEnvironment * environment() const
#define ASSERT(condition)
virtual const char * Mnemonic() const =0
virtual void PrintDataTo(StringStream *stream)
void PrintTo(StringStream *stream)
bool IsSimpleMapChangeTransition(ElementsKind from_kind, ElementsKind to_kind)
#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V)
Representation representation() const
EqualityKind kind() const
virtual void PrintDataTo(StringStream *stream)
virtual void PrintDataTo(StringStream *stream)
virtual void PrintDataTo(StringStream *stream)
virtual bool HasResult() const =0
virtual void PrintDataTo(StringStream *stream)
void PrintTo(StringStream *stream)
LLabel * replacement() const
static HUnaryOperation * cast(HValue *value)
virtual const char * Mnemonic() const
virtual void PrintDataTo(StringStream *stream)
virtual void PrintDataTo(StringStream *stream)
void MarkSpilledRegister(int allocation_index, LOperand *spill_operand)
static const char * String(Value tok)
static LDoubleStackSlot * Create(int index, Zone *zone)
virtual void PrintDataTo(StringStream *stream)
bool HasEnvironment() const
virtual void PrintDataTo(StringStream *stream)
virtual LOperand * result()=0
virtual void PrintDataTo(StringStream *stream)
static int ToAllocationIndex(Register reg)
virtual void PrintDataTo(StringStream *stream)
virtual void PrintTo(StringStream *stream)
virtual void PrintDataTo(StringStream *stream)
static LStackSlot * Create(int index, Zone *zone)
virtual void PrintDataTo(StringStream *stream)
static const int kMaxFixedIndex
LPointerMap * pointer_map() const
static int ToAllocationIndex(XMMRegister reg)
virtual void PrintDataTo(StringStream *stream)
virtual DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,"string-compare-and-branch") Token void PrintDataTo(StringStream *stream)
virtual void PrintDataTo(StringStream *stream)
void PrintDataTo(StringStream *stream) const
virtual const char * Mnemonic() const
static const int kNumAllocatableRegisters
#define ASSERT_EQ(v1, v2)
virtual void PrintDataTo(StringStream *stream)
virtual void PrintDataTo(StringStream *stream)
Handle< String > name() const
virtual void PrintDataTo(StringStream *stream)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
bool HasPointerMap() const
virtual void PrintDataTo(StringStream *stream)
static HValue * cast(HValue *value)
Handle< String > type_literal()
void PrintTo(StringStream *stream)
virtual void PrintDataTo(StringStream *stream)
Handle< Map > original_map()
virtual void PrintDataTo(StringStream *stream)
virtual void PrintDataTo(StringStream *stream)