OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 1538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1549 } | 1549 } |
1550 | 1550 |
1551 | 1551 |
1552 void LCodeGen::DoConstantE(LConstantE* instr) { | 1552 void LCodeGen::DoConstantE(LConstantE* instr) { |
1553 __ LoadAddress(ToRegister(instr->result()), instr->value()); | 1553 __ LoadAddress(ToRegister(instr->result()), instr->value()); |
1554 } | 1554 } |
1555 | 1555 |
1556 | 1556 |
1557 void LCodeGen::DoConstantT(LConstantT* instr) { | 1557 void LCodeGen::DoConstantT(LConstantT* instr) { |
1558 Handle<Object> value = instr->value(isolate()); | 1558 Handle<Object> value = instr->value(isolate()); |
1559 AllowDeferredHandleDereference smi_check; | 1559 __ Move(ToRegister(instr->result()), value); |
1560 __ LoadObject(ToRegister(instr->result()), value); | |
1561 } | 1560 } |
1562 | 1561 |
1563 | 1562 |
1564 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { | 1563 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { |
1565 Register result = ToRegister(instr->result()); | 1564 Register result = ToRegister(instr->result()); |
1566 Register map = ToRegister(instr->value()); | 1565 Register map = ToRegister(instr->value()); |
1567 __ EnumLength(result, map); | 1566 __ EnumLength(result, map); |
1568 } | 1567 } |
1569 | 1568 |
1570 | 1569 |
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2122 EmitBranch(instr, cc); | 2121 EmitBranch(instr, cc); |
2123 } | 2122 } |
2124 } | 2123 } |
2125 | 2124 |
2126 | 2125 |
2127 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { | 2126 void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { |
2128 Register left = ToRegister(instr->left()); | 2127 Register left = ToRegister(instr->left()); |
2129 | 2128 |
2130 if (instr->right()->IsConstantOperand()) { | 2129 if (instr->right()->IsConstantOperand()) { |
2131 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right())); | 2130 Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right())); |
2132 __ CmpObject(left, right); | 2131 __ Cmp(left, right); |
2133 } else { | 2132 } else { |
2134 Register right = ToRegister(instr->right()); | 2133 Register right = ToRegister(instr->right()); |
2135 __ cmpq(left, right); | 2134 __ cmpq(left, right); |
2136 } | 2135 } |
2137 EmitBranch(instr, equal); | 2136 EmitBranch(instr, equal); |
2138 } | 2137 } |
2139 | 2138 |
2140 | 2139 |
2141 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) { | 2140 void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) { |
2142 if (instr->hydrogen()->representation().IsTagged()) { | 2141 if (instr->hydrogen()->representation().IsTagged()) { |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2490 | 2489 |
2491 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, | 2490 void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, |
2492 Label* map_check) { | 2491 Label* map_check) { |
2493 { | 2492 { |
2494 PushSafepointRegistersScope scope(this); | 2493 PushSafepointRegistersScope scope(this); |
2495 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>( | 2494 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>( |
2496 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck); | 2495 InstanceofStub::kNoFlags | InstanceofStub::kCallSiteInlineCheck); |
2497 InstanceofStub stub(flags); | 2496 InstanceofStub stub(flags); |
2498 | 2497 |
2499 __ push(ToRegister(instr->value())); | 2498 __ push(ToRegister(instr->value())); |
2500 __ PushHeapObject(instr->function()); | 2499 __ Push(instr->function()); |
2501 | 2500 |
2502 static const int kAdditionalDelta = 10; | 2501 static const int kAdditionalDelta = 10; |
2503 int delta = | 2502 int delta = |
2504 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; | 2503 masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta; |
2505 ASSERT(delta >= 0); | 2504 ASSERT(delta >= 0); |
2506 __ push_imm32(delta); | 2505 __ push_imm32(delta); |
2507 | 2506 |
2508 // We are pushing three values on the stack but recording a | 2507 // We are pushing three values on the stack but recording a |
2509 // safepoint with two arguments because stub is going to | 2508 // safepoint with two arguments because stub is going to |
2510 // remove the third argument from the stack before jumping | 2509 // remove the third argument from the stack before jumping |
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3201 void LCodeGen::DoOuterContext(LOuterContext* instr) { | 3200 void LCodeGen::DoOuterContext(LOuterContext* instr) { |
3202 Register context = ToRegister(instr->context()); | 3201 Register context = ToRegister(instr->context()); |
3203 Register result = ToRegister(instr->result()); | 3202 Register result = ToRegister(instr->result()); |
3204 __ movq(result, | 3203 __ movq(result, |
3205 Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX))); | 3204 Operand(context, Context::SlotOffset(Context::PREVIOUS_INDEX))); |
3206 } | 3205 } |
3207 | 3206 |
3208 | 3207 |
3209 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { | 3208 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { |
3210 __ push(rsi); // The context is the first argument. | 3209 __ push(rsi); // The context is the first argument. |
3211 __ PushHeapObject(instr->hydrogen()->pairs()); | 3210 __ Push(instr->hydrogen()->pairs()); |
3212 __ Push(Smi::FromInt(instr->hydrogen()->flags())); | 3211 __ Push(Smi::FromInt(instr->hydrogen()->flags())); |
3213 CallRuntime(Runtime::kDeclareGlobals, 3, instr); | 3212 CallRuntime(Runtime::kDeclareGlobals, 3, instr); |
3214 } | 3213 } |
3215 | 3214 |
3216 | 3215 |
3217 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { | 3216 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { |
3218 Register result = ToRegister(instr->result()); | 3217 Register result = ToRegister(instr->result()); |
3219 __ movq(result, GlobalObjectOperand()); | 3218 __ movq(result, GlobalObjectOperand()); |
3220 } | 3219 } |
3221 | 3220 |
(...skipping 13 matching lines...) Expand all Loading... |
3235 RDIState rdi_state) { | 3234 RDIState rdi_state) { |
3236 bool dont_adapt_arguments = | 3235 bool dont_adapt_arguments = |
3237 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 3236 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
3238 bool can_invoke_directly = | 3237 bool can_invoke_directly = |
3239 dont_adapt_arguments || formal_parameter_count == arity; | 3238 dont_adapt_arguments || formal_parameter_count == arity; |
3240 | 3239 |
3241 LPointerMap* pointers = instr->pointer_map(); | 3240 LPointerMap* pointers = instr->pointer_map(); |
3242 | 3241 |
3243 if (can_invoke_directly) { | 3242 if (can_invoke_directly) { |
3244 if (rdi_state == RDI_UNINITIALIZED) { | 3243 if (rdi_state == RDI_UNINITIALIZED) { |
3245 __ LoadHeapObject(rdi, function); | 3244 __ Move(rdi, function); |
3246 } | 3245 } |
3247 | 3246 |
3248 // Change context. | 3247 // Change context. |
3249 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 3248 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
3250 | 3249 |
3251 // Set rax to arguments count if adaption is not needed. Assumes that rax | 3250 // Set rax to arguments count if adaption is not needed. Assumes that rax |
3252 // is available to write to at this point. | 3251 // is available to write to at this point. |
3253 if (dont_adapt_arguments) { | 3252 if (dont_adapt_arguments) { |
3254 __ Set(rax, arity); | 3253 __ Set(rax, arity); |
3255 } | 3254 } |
(...skipping 1575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4831 __ andb(kScratchRegister, Immediate(mask)); | 4830 __ andb(kScratchRegister, Immediate(mask)); |
4832 __ cmpb(kScratchRegister, Immediate(tag)); | 4831 __ cmpb(kScratchRegister, Immediate(tag)); |
4833 DeoptimizeIf(not_equal, instr->environment()); | 4832 DeoptimizeIf(not_equal, instr->environment()); |
4834 } | 4833 } |
4835 } | 4834 } |
4836 } | 4835 } |
4837 | 4836 |
4838 | 4837 |
4839 void LCodeGen::DoCheckValue(LCheckValue* instr) { | 4838 void LCodeGen::DoCheckValue(LCheckValue* instr) { |
4840 Register reg = ToRegister(instr->value()); | 4839 Register reg = ToRegister(instr->value()); |
4841 Handle<HeapObject> object = instr->hydrogen()->object().handle(); | 4840 __ Cmp(reg, instr->hydrogen()->object().handle()); |
4842 __ CmpHeapObject(reg, object); | |
4843 DeoptimizeIf(not_equal, instr->environment()); | 4841 DeoptimizeIf(not_equal, instr->environment()); |
4844 } | 4842 } |
4845 | 4843 |
4846 | 4844 |
4847 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { | 4845 void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { |
4848 { | 4846 { |
4849 PushSafepointRegistersScope scope(this); | 4847 PushSafepointRegistersScope scope(this); |
4850 __ push(object); | 4848 __ push(object); |
4851 CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr); | 4849 CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr); |
4852 __ testq(rax, Immediate(kSmiTagMask)); | 4850 __ testq(rax, Immediate(kSmiTagMask)); |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5059 | 5057 |
5060 | 5058 |
5061 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { | 5059 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { |
5062 Label materialized; | 5060 Label materialized; |
5063 // Registers will be used as follows: | 5061 // Registers will be used as follows: |
5064 // rcx = literals array. | 5062 // rcx = literals array. |
5065 // rbx = regexp literal. | 5063 // rbx = regexp literal. |
5066 // rax = regexp literal clone. | 5064 // rax = regexp literal clone. |
5067 int literal_offset = | 5065 int literal_offset = |
5068 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); | 5066 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); |
5069 __ LoadHeapObject(rcx, instr->hydrogen()->literals()); | 5067 __ Move(rcx, instr->hydrogen()->literals()); |
5070 __ movq(rbx, FieldOperand(rcx, literal_offset)); | 5068 __ movq(rbx, FieldOperand(rcx, literal_offset)); |
5071 __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex); | 5069 __ CompareRoot(rbx, Heap::kUndefinedValueRootIndex); |
5072 __ j(not_equal, &materialized, Label::kNear); | 5070 __ j(not_equal, &materialized, Label::kNear); |
5073 | 5071 |
5074 // Create regexp literal using runtime function | 5072 // Create regexp literal using runtime function |
5075 // Result will be in rax. | 5073 // Result will be in rax. |
5076 __ push(rcx); | 5074 __ push(rcx); |
5077 __ Push(Smi::FromInt(instr->hydrogen()->literal_index())); | 5075 __ Push(Smi::FromInt(instr->hydrogen()->literal_index())); |
5078 __ Push(instr->hydrogen()->pattern()); | 5076 __ Push(instr->hydrogen()->pattern()); |
5079 __ Push(instr->hydrogen()->flags()); | 5077 __ Push(instr->hydrogen()->flags()); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5130 void LCodeGen::DoTypeof(LTypeof* instr) { | 5128 void LCodeGen::DoTypeof(LTypeof* instr) { |
5131 LOperand* input = instr->value(); | 5129 LOperand* input = instr->value(); |
5132 EmitPushTaggedOperand(input); | 5130 EmitPushTaggedOperand(input); |
5133 CallRuntime(Runtime::kTypeof, 1, instr); | 5131 CallRuntime(Runtime::kTypeof, 1, instr); |
5134 } | 5132 } |
5135 | 5133 |
5136 | 5134 |
5137 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { | 5135 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { |
5138 ASSERT(!operand->IsDoubleRegister()); | 5136 ASSERT(!operand->IsDoubleRegister()); |
5139 if (operand->IsConstantOperand()) { | 5137 if (operand->IsConstantOperand()) { |
5140 Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); | 5138 __ Push(ToHandle(LConstantOperand::cast(operand))); |
5141 AllowDeferredHandleDereference smi_check; | |
5142 if (object->IsSmi()) { | |
5143 __ Push(Handle<Smi>::cast(object)); | |
5144 } else { | |
5145 __ PushHeapObject(Handle<HeapObject>::cast(object)); | |
5146 } | |
5147 } else if (operand->IsRegister()) { | 5139 } else if (operand->IsRegister()) { |
5148 __ push(ToRegister(operand)); | 5140 __ push(ToRegister(operand)); |
5149 } else { | 5141 } else { |
5150 __ push(ToOperand(operand)); | 5142 __ push(ToOperand(operand)); |
5151 } | 5143 } |
5152 } | 5144 } |
5153 | 5145 |
5154 | 5146 |
5155 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { | 5147 void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { |
5156 Register input = ToRegister(instr->value()); | 5148 Register input = ToRegister(instr->value()); |
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5470 FixedArray::kHeaderSize - kPointerSize)); | 5462 FixedArray::kHeaderSize - kPointerSize)); |
5471 __ bind(&done); | 5463 __ bind(&done); |
5472 } | 5464 } |
5473 | 5465 |
5474 | 5466 |
5475 #undef __ | 5467 #undef __ |
5476 | 5468 |
5477 } } // namespace v8::internal | 5469 } } // namespace v8::internal |
5478 | 5470 |
5479 #endif // V8_TARGET_ARCH_X64 | 5471 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |