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 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1100 // Nothing to do. | 1100 // Nothing to do. |
1101 } | 1101 } |
1102 | 1102 |
1103 | 1103 |
1104 void LCodeGen::DoCallStub(LCallStub* instr) { | 1104 void LCodeGen::DoCallStub(LCallStub* instr) { |
1105 ASSERT(ToRegister(instr->context()).is(cp)); | 1105 ASSERT(ToRegister(instr->context()).is(cp)); |
1106 ASSERT(ToRegister(instr->result()).is(r0)); | 1106 ASSERT(ToRegister(instr->result()).is(r0)); |
1107 switch (instr->hydrogen()->major_key()) { | 1107 switch (instr->hydrogen()->major_key()) { |
1108 case CodeStub::RegExpExec: { | 1108 case CodeStub::RegExpExec: { |
1109 RegExpExecStub stub(isolate()); | 1109 RegExpExecStub stub(isolate()); |
1110 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1110 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1111 break; | 1111 break; |
1112 } | 1112 } |
1113 case CodeStub::SubString: { | 1113 case CodeStub::SubString: { |
1114 SubStringStub stub(isolate()); | 1114 SubStringStub stub(isolate()); |
1115 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1115 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1116 break; | 1116 break; |
1117 } | 1117 } |
1118 case CodeStub::StringCompare: { | 1118 case CodeStub::StringCompare: { |
1119 StringCompareStub stub(isolate()); | 1119 StringCompareStub stub(isolate()); |
1120 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 1120 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
1121 break; | 1121 break; |
1122 } | 1122 } |
1123 default: | 1123 default: |
1124 UNREACHABLE(); | 1124 UNREACHABLE(); |
1125 } | 1125 } |
1126 } | 1126 } |
1127 | 1127 |
1128 | 1128 |
1129 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { | 1129 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { |
1130 GenerateOsrPrologue(); | 1130 GenerateOsrPrologue(); |
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2156 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { | 2156 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { |
2157 ASSERT(ToRegister(instr->context()).is(cp)); | 2157 ASSERT(ToRegister(instr->context()).is(cp)); |
2158 ASSERT(ToRegister(instr->left()).is(r1)); | 2158 ASSERT(ToRegister(instr->left()).is(r1)); |
2159 ASSERT(ToRegister(instr->right()).is(r0)); | 2159 ASSERT(ToRegister(instr->right()).is(r0)); |
2160 ASSERT(ToRegister(instr->result()).is(r0)); | 2160 ASSERT(ToRegister(instr->result()).is(r0)); |
2161 | 2161 |
2162 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); | 2162 BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); |
2163 // Block literal pool emission to ensure nop indicating no inlined smi code | 2163 // Block literal pool emission to ensure nop indicating no inlined smi code |
2164 // is in the correct position. | 2164 // is in the correct position. |
2165 Assembler::BlockConstPoolScope block_const_pool(masm()); | 2165 Assembler::BlockConstPoolScope block_const_pool(masm()); |
2166 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 2166 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
2167 } | 2167 } |
2168 | 2168 |
2169 | 2169 |
2170 template<class InstrType> | 2170 template<class InstrType> |
2171 void LCodeGen::EmitBranch(InstrType instr, Condition condition) { | 2171 void LCodeGen::EmitBranch(InstrType instr, Condition condition) { |
2172 int left_block = instr->TrueDestination(chunk_); | 2172 int left_block = instr->TrueDestination(chunk_); |
2173 int right_block = instr->FalseDestination(chunk_); | 2173 int right_block = instr->FalseDestination(chunk_); |
2174 | 2174 |
2175 int next_block = GetNextEmittedBlock(); | 2175 int next_block = GetNextEmittedBlock(); |
2176 | 2176 |
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2748 EmitBranch(instr, eq); | 2748 EmitBranch(instr, eq); |
2749 } | 2749 } |
2750 | 2750 |
2751 | 2751 |
2752 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { | 2752 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { |
2753 ASSERT(ToRegister(instr->context()).is(cp)); | 2753 ASSERT(ToRegister(instr->context()).is(cp)); |
2754 ASSERT(ToRegister(instr->left()).is(r0)); // Object is in r0. | 2754 ASSERT(ToRegister(instr->left()).is(r0)); // Object is in r0. |
2755 ASSERT(ToRegister(instr->right()).is(r1)); // Function is in r1. | 2755 ASSERT(ToRegister(instr->right()).is(r1)); // Function is in r1. |
2756 | 2756 |
2757 InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters); | 2757 InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters); |
2758 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 2758 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
2759 | 2759 |
2760 __ cmp(r0, Operand::Zero()); | 2760 __ cmp(r0, Operand::Zero()); |
2761 __ mov(r0, Operand(factory()->false_value()), LeaveCC, ne); | 2761 __ mov(r0, Operand(factory()->false_value()), LeaveCC, ne); |
2762 __ mov(r0, Operand(factory()->true_value()), LeaveCC, eq); | 2762 __ mov(r0, Operand(factory()->true_value()), LeaveCC, eq); |
2763 } | 2763 } |
2764 | 2764 |
2765 | 2765 |
2766 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { | 2766 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { |
2767 class DeferredInstanceOfKnownGlobal V8_FINAL : public LDeferredCode { | 2767 class DeferredInstanceOfKnownGlobal V8_FINAL : public LDeferredCode { |
2768 public: | 2768 public: |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2866 __ bind(&before_push_delta); | 2866 __ bind(&before_push_delta); |
2867 __ BlockConstPoolFor(kAdditionalDelta); | 2867 __ BlockConstPoolFor(kAdditionalDelta); |
2868 // r5 is used to communicate the offset to the location of the map check. | 2868 // r5 is used to communicate the offset to the location of the map check. |
2869 __ mov(r5, Operand(delta * kPointerSize)); | 2869 __ mov(r5, Operand(delta * kPointerSize)); |
2870 // The mov above can generate one or two instructions. The delta was computed | 2870 // The mov above can generate one or two instructions. The delta was computed |
2871 // for two instructions, so we need to pad here in case of one instruction. | 2871 // for two instructions, so we need to pad here in case of one instruction. |
2872 if (masm_->InstructionsGeneratedSince(&before_push_delta) != 2) { | 2872 if (masm_->InstructionsGeneratedSince(&before_push_delta) != 2) { |
2873 ASSERT_EQ(1, masm_->InstructionsGeneratedSince(&before_push_delta)); | 2873 ASSERT_EQ(1, masm_->InstructionsGeneratedSince(&before_push_delta)); |
2874 __ nop(); | 2874 __ nop(); |
2875 } | 2875 } |
2876 CallCodeGeneric(stub.GetCode(isolate()), | 2876 CallCodeGeneric(stub.GetCode(), |
2877 RelocInfo::CODE_TARGET, | 2877 RelocInfo::CODE_TARGET, |
2878 instr, | 2878 instr, |
2879 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); | 2879 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); |
2880 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); | 2880 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); |
2881 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 2881 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |
2882 // Put the result value (r0) into the result register slot and | 2882 // Put the result value (r0) into the result register slot and |
2883 // restore all registers. | 2883 // restore all registers. |
2884 __ StoreToSafepointRegisterSlot(r0, ToRegister(instr->result())); | 2884 __ StoreToSafepointRegisterSlot(r0, ToRegister(instr->result())); |
2885 } | 2885 } |
2886 | 2886 |
(...skipping 1101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3988 } | 3988 } |
3989 | 3989 |
3990 | 3990 |
3991 void LCodeGen::DoCallFunction(LCallFunction* instr) { | 3991 void LCodeGen::DoCallFunction(LCallFunction* instr) { |
3992 ASSERT(ToRegister(instr->context()).is(cp)); | 3992 ASSERT(ToRegister(instr->context()).is(cp)); |
3993 ASSERT(ToRegister(instr->function()).is(r1)); | 3993 ASSERT(ToRegister(instr->function()).is(r1)); |
3994 ASSERT(ToRegister(instr->result()).is(r0)); | 3994 ASSERT(ToRegister(instr->result()).is(r0)); |
3995 | 3995 |
3996 int arity = instr->arity(); | 3996 int arity = instr->arity(); |
3997 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags()); | 3997 CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags()); |
3998 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 3998 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
3999 } | 3999 } |
4000 | 4000 |
4001 | 4001 |
4002 void LCodeGen::DoCallNew(LCallNew* instr) { | 4002 void LCodeGen::DoCallNew(LCallNew* instr) { |
4003 ASSERT(ToRegister(instr->context()).is(cp)); | 4003 ASSERT(ToRegister(instr->context()).is(cp)); |
4004 ASSERT(ToRegister(instr->constructor()).is(r1)); | 4004 ASSERT(ToRegister(instr->constructor()).is(r1)); |
4005 ASSERT(ToRegister(instr->result()).is(r0)); | 4005 ASSERT(ToRegister(instr->result()).is(r0)); |
4006 | 4006 |
4007 __ mov(r0, Operand(instr->arity())); | 4007 __ mov(r0, Operand(instr->arity())); |
4008 // No cell in r2 for construct type feedback in optimized code | 4008 // No cell in r2 for construct type feedback in optimized code |
4009 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 4009 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
4010 CallConstructStub stub(isolate(), NO_CALL_FUNCTION_FLAGS); | 4010 CallConstructStub stub(isolate(), NO_CALL_FUNCTION_FLAGS); |
4011 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4011 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
4012 } | 4012 } |
4013 | 4013 |
4014 | 4014 |
4015 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { | 4015 void LCodeGen::DoCallNewArray(LCallNewArray* instr) { |
4016 ASSERT(ToRegister(instr->context()).is(cp)); | 4016 ASSERT(ToRegister(instr->context()).is(cp)); |
4017 ASSERT(ToRegister(instr->constructor()).is(r1)); | 4017 ASSERT(ToRegister(instr->constructor()).is(r1)); |
4018 ASSERT(ToRegister(instr->result()).is(r0)); | 4018 ASSERT(ToRegister(instr->result()).is(r0)); |
4019 | 4019 |
4020 __ mov(r0, Operand(instr->arity())); | 4020 __ mov(r0, Operand(instr->arity())); |
4021 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 4021 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
4022 ElementsKind kind = instr->hydrogen()->elements_kind(); | 4022 ElementsKind kind = instr->hydrogen()->elements_kind(); |
4023 AllocationSiteOverrideMode override_mode = | 4023 AllocationSiteOverrideMode override_mode = |
4024 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) | 4024 (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) |
4025 ? DISABLE_ALLOCATION_SITES | 4025 ? DISABLE_ALLOCATION_SITES |
4026 : DONT_OVERRIDE; | 4026 : DONT_OVERRIDE; |
4027 | 4027 |
4028 if (instr->arity() == 0) { | 4028 if (instr->arity() == 0) { |
4029 ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode); | 4029 ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode); |
4030 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4030 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
4031 } else if (instr->arity() == 1) { | 4031 } else if (instr->arity() == 1) { |
4032 Label done; | 4032 Label done; |
4033 if (IsFastPackedElementsKind(kind)) { | 4033 if (IsFastPackedElementsKind(kind)) { |
4034 Label packed_case; | 4034 Label packed_case; |
4035 // We might need a change here | 4035 // We might need a change here |
4036 // look at the first argument | 4036 // look at the first argument |
4037 __ ldr(r5, MemOperand(sp, 0)); | 4037 __ ldr(r5, MemOperand(sp, 0)); |
4038 __ cmp(r5, Operand::Zero()); | 4038 __ cmp(r5, Operand::Zero()); |
4039 __ b(eq, &packed_case); | 4039 __ b(eq, &packed_case); |
4040 | 4040 |
4041 ElementsKind holey_kind = GetHoleyElementsKind(kind); | 4041 ElementsKind holey_kind = GetHoleyElementsKind(kind); |
4042 ArraySingleArgumentConstructorStub stub(isolate(), | 4042 ArraySingleArgumentConstructorStub stub(isolate(), |
4043 holey_kind, | 4043 holey_kind, |
4044 override_mode); | 4044 override_mode); |
4045 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4045 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
4046 __ jmp(&done); | 4046 __ jmp(&done); |
4047 __ bind(&packed_case); | 4047 __ bind(&packed_case); |
4048 } | 4048 } |
4049 | 4049 |
4050 ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode); | 4050 ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode); |
4051 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4051 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
4052 __ bind(&done); | 4052 __ bind(&done); |
4053 } else { | 4053 } else { |
4054 ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); | 4054 ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode); |
4055 CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr); | 4055 CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr); |
4056 } | 4056 } |
4057 } | 4057 } |
4058 | 4058 |
4059 | 4059 |
4060 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { | 4060 void LCodeGen::DoCallRuntime(LCallRuntime* instr) { |
4061 CallRuntime(instr->function(), instr->arity(), instr); | 4061 CallRuntime(instr->function(), instr->arity(), instr); |
4062 } | 4062 } |
4063 | 4063 |
4064 | 4064 |
4065 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) { | 4065 void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) { |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4467 } | 4467 } |
4468 | 4468 |
4469 | 4469 |
4470 void LCodeGen::DoStringAdd(LStringAdd* instr) { | 4470 void LCodeGen::DoStringAdd(LStringAdd* instr) { |
4471 ASSERT(ToRegister(instr->context()).is(cp)); | 4471 ASSERT(ToRegister(instr->context()).is(cp)); |
4472 ASSERT(ToRegister(instr->left()).is(r1)); | 4472 ASSERT(ToRegister(instr->left()).is(r1)); |
4473 ASSERT(ToRegister(instr->right()).is(r0)); | 4473 ASSERT(ToRegister(instr->right()).is(r0)); |
4474 StringAddStub stub(isolate(), | 4474 StringAddStub stub(isolate(), |
4475 instr->hydrogen()->flags(), | 4475 instr->hydrogen()->flags(), |
4476 instr->hydrogen()->pretenure_flag()); | 4476 instr->hydrogen()->pretenure_flag()); |
4477 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4477 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
4478 } | 4478 } |
4479 | 4479 |
4480 | 4480 |
4481 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { | 4481 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
4482 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { | 4482 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { |
4483 public: | 4483 public: |
4484 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) | 4484 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) |
4485 : LDeferredCode(codegen), instr_(instr) { } | 4485 : LDeferredCode(codegen), instr_(instr) { } |
4486 virtual void Generate() V8_OVERRIDE { | 4486 virtual void Generate() V8_OVERRIDE { |
4487 codegen()->DoDeferredStringCharCodeAt(instr_); | 4487 codegen()->DoDeferredStringCharCodeAt(instr_); |
(...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5447 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { | 5447 void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { |
5448 ASSERT(ToRegister(instr->context()).is(cp)); | 5448 ASSERT(ToRegister(instr->context()).is(cp)); |
5449 // Use the fast case closure allocation code that allocates in new | 5449 // Use the fast case closure allocation code that allocates in new |
5450 // space for nested functions that don't need literals cloning. | 5450 // space for nested functions that don't need literals cloning. |
5451 bool pretenure = instr->hydrogen()->pretenure(); | 5451 bool pretenure = instr->hydrogen()->pretenure(); |
5452 if (!pretenure && instr->hydrogen()->has_no_literals()) { | 5452 if (!pretenure && instr->hydrogen()->has_no_literals()) { |
5453 FastNewClosureStub stub(isolate(), | 5453 FastNewClosureStub stub(isolate(), |
5454 instr->hydrogen()->strict_mode(), | 5454 instr->hydrogen()->strict_mode(), |
5455 instr->hydrogen()->is_generator()); | 5455 instr->hydrogen()->is_generator()); |
5456 __ mov(r2, Operand(instr->hydrogen()->shared_info())); | 5456 __ mov(r2, Operand(instr->hydrogen()->shared_info())); |
5457 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 5457 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
5458 } else { | 5458 } else { |
5459 __ mov(r2, Operand(instr->hydrogen()->shared_info())); | 5459 __ mov(r2, Operand(instr->hydrogen()->shared_info())); |
5460 __ mov(r1, Operand(pretenure ? factory()->true_value() | 5460 __ mov(r1, Operand(pretenure ? factory()->true_value() |
5461 : factory()->false_value())); | 5461 : factory()->false_value())); |
5462 __ Push(cp, r2, r1); | 5462 __ Push(cp, r2, r1); |
5463 CallRuntime(Runtime::kHiddenNewClosure, 3, instr); | 5463 CallRuntime(Runtime::kHiddenNewClosure, 3, instr); |
5464 } | 5464 } |
5465 } | 5465 } |
5466 | 5466 |
5467 | 5467 |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5859 __ ldr(result, FieldMemOperand(scratch, | 5859 __ ldr(result, FieldMemOperand(scratch, |
5860 FixedArray::kHeaderSize - kPointerSize)); | 5860 FixedArray::kHeaderSize - kPointerSize)); |
5861 __ bind(deferred->exit()); | 5861 __ bind(deferred->exit()); |
5862 __ bind(&done); | 5862 __ bind(&done); |
5863 } | 5863 } |
5864 | 5864 |
5865 | 5865 |
5866 #undef __ | 5866 #undef __ |
5867 | 5867 |
5868 } } // namespace v8::internal | 5868 } } // namespace v8::internal |
OLD | NEW |