OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 4530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4541 DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister())); | 4541 DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister())); |
4542 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); | 4542 DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister())); |
4543 | 4543 |
4544 Handle<Code> ic = CodeFactory::KeyedStoreICInOptimizedCode( | 4544 Handle<Code> ic = CodeFactory::KeyedStoreICInOptimizedCode( |
4545 isolate(), instr->language_mode(), | 4545 isolate(), instr->language_mode(), |
4546 instr->hydrogen()->initialization_state()).code(); | 4546 instr->hydrogen()->initialization_state()).code(); |
4547 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 4547 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
4548 } | 4548 } |
4549 | 4549 |
4550 | 4550 |
4551 void LCodeGen::DoMaybeGrowElements(LMaybeGrowElements* instr) { | |
4552 class DeferredMaybeGrowElements final : public LDeferredCode { | |
4553 public: | |
4554 DeferredMaybeGrowElements(LCodeGen* codegen, LMaybeGrowElements* instr) | |
4555 : LDeferredCode(codegen), instr_(instr) {} | |
4556 void Generate() override { codegen()->DoDeferredMaybeGrowElements(instr_); } | |
4557 LInstruction* instr() override { return instr_; } | |
4558 | |
4559 private: | |
4560 LMaybeGrowElements* instr_; | |
4561 }; | |
4562 | |
4563 Register result = rax; | |
4564 DeferredMaybeGrowElements* deferred = | |
4565 new (zone()) DeferredMaybeGrowElements(this, instr); | |
4566 LOperand* key = instr->key(); | |
4567 LOperand* current_capacity = instr->current_capacity(); | |
4568 | |
4569 DCHECK(instr->hydrogen()->key()->representation().IsInteger32()); | |
4570 DCHECK(instr->hydrogen()->current_capacity()->representation().IsInteger32()); | |
4571 DCHECK(key->IsConstantOperand() || key->IsRegister()); | |
4572 DCHECK(current_capacity->IsConstantOperand() || | |
4573 current_capacity->IsRegister()); | |
4574 | |
4575 if (key->IsConstantOperand() && current_capacity->IsConstantOperand()) { | |
4576 int32_t constant_key = ToInteger32(LConstantOperand::cast(key)); | |
4577 int32_t constant_capacity = | |
4578 ToInteger32(LConstantOperand::cast(current_capacity)); | |
4579 if (constant_key >= constant_capacity) { | |
4580 // Deferred case. | |
4581 __ jmp(deferred->entry()); | |
4582 } | |
4583 } else if (key->IsConstantOperand()) { | |
4584 int32_t constant_key = ToInteger32(LConstantOperand::cast(key)); | |
4585 __ cmpl(ToRegister(current_capacity), Immediate(constant_key)); | |
4586 __ j(less_equal, deferred->entry()); | |
4587 } else if (current_capacity->IsConstantOperand()) { | |
4588 int32_t constant_capacity = | |
4589 ToInteger32(LConstantOperand::cast(current_capacity)); | |
4590 __ cmpl(ToRegister(key), Immediate(constant_capacity)); | |
4591 __ j(greater_equal, deferred->entry()); | |
4592 } else { | |
4593 __ cmpl(ToRegister(key), ToRegister(current_capacity)); | |
4594 __ j(greater_equal, deferred->entry()); | |
4595 } | |
4596 | |
4597 if (instr->elements()->IsRegister()) { | |
4598 __ movp(result, ToRegister(instr->elements())); | |
4599 } else { | |
4600 __ movp(result, ToOperand(instr->elements())); | |
4601 } | |
4602 | |
4603 __ bind(deferred->exit()); | |
4604 } | |
4605 | |
4606 | |
4607 void LCodeGen::DoDeferredMaybeGrowElements(LMaybeGrowElements* instr) { | |
4608 // TODO(3095996): Get rid of this. For now, we need to make the | |
4609 // result register contain a valid pointer because it is already | |
4610 // contained in the register pointer map. | |
4611 Register result = rax; | |
4612 __ Move(result, Smi::FromInt(0)); | |
4613 | |
4614 // We have to call a stub. | |
4615 { | |
4616 PushSafepointRegistersScope scope(this); | |
4617 if (instr->object()->IsConstantOperand()) { | |
4618 LConstantOperand* constant_object = | |
4619 LConstantOperand::cast(instr->object()); | |
4620 if (IsSmiConstant(constant_object)) { | |
4621 Smi* immediate = ToSmi(constant_object); | |
4622 __ Move(result, immediate); | |
4623 } else { | |
4624 Handle<Object> handle_value = ToHandle(constant_object); | |
4625 __ Move(result, handle_value); | |
4626 } | |
4627 } else if (instr->object()->IsRegister()) { | |
4628 __ Move(result, ToRegister(instr->object())); | |
4629 } else { | |
4630 __ movp(result, ToOperand(instr->object())); | |
4631 } | |
4632 | |
4633 LOperand* key = instr->key(); | |
4634 if (key->IsConstantOperand()) { | |
4635 __ Move(rbx, ToSmi(LConstantOperand::cast(key))); | |
4636 } else { | |
4637 __ Move(rbx, ToRegister(key)); | |
4638 __ Integer32ToSmi(rbx, rbx); | |
4639 } | |
4640 | |
4641 GrowArrayElementsStub stub(isolate(), instr->hydrogen()->is_js_array(), | |
4642 instr->hydrogen()->kind()); | |
4643 __ CallStub(&stub); | |
4644 RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0); | |
4645 __ StoreToSafepointRegisterSlot(result, result); | |
4646 } | |
4647 | |
4648 // Deoptimize if we got a smi back. | |
Benedikt Meurer
2015/05/12 05:13:04
Please add a comment here to describe why we deopt
mvstanton
2015/05/12 07:59:03
Good idea, done.
| |
4649 Condition is_smi = __ CheckSmi(result); | |
4650 DeoptimizeIf(is_smi, instr, Deoptimizer::kSmi); | |
4651 } | |
4652 | |
4653 | |
4551 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { | 4654 void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { |
4552 Register object_reg = ToRegister(instr->object()); | 4655 Register object_reg = ToRegister(instr->object()); |
4553 | 4656 |
4554 Handle<Map> from_map = instr->original_map(); | 4657 Handle<Map> from_map = instr->original_map(); |
4555 Handle<Map> to_map = instr->transitioned_map(); | 4658 Handle<Map> to_map = instr->transitioned_map(); |
4556 ElementsKind from_kind = instr->from_kind(); | 4659 ElementsKind from_kind = instr->from_kind(); |
4557 ElementsKind to_kind = instr->to_kind(); | 4660 ElementsKind to_kind = instr->to_kind(); |
4558 | 4661 |
4559 Label not_applicable; | 4662 Label not_applicable; |
4560 __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); | 4663 __ Cmp(FieldOperand(object_reg, HeapObject::kMapOffset), from_map); |
(...skipping 1391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5952 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6055 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
5953 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6056 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5954 } | 6057 } |
5955 | 6058 |
5956 | 6059 |
5957 #undef __ | 6060 #undef __ |
5958 | 6061 |
5959 } } // namespace v8::internal | 6062 } } // namespace v8::internal |
5960 | 6063 |
5961 #endif // V8_TARGET_ARCH_X64 | 6064 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |