| 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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 code->set_stack_slots(GetStackSlotCount()); | 84 code->set_stack_slots(GetStackSlotCount()); |
| 85 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); | 85 code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); |
| 86 if (FLAG_weak_embedded_maps_in_optimized_code) { | 86 if (FLAG_weak_embedded_maps_in_optimized_code) { |
| 87 RegisterDependentCodeForEmbeddedMaps(code); | 87 RegisterDependentCodeForEmbeddedMaps(code); |
| 88 } | 88 } |
| 89 PopulateDeoptimizationData(code); | 89 PopulateDeoptimizationData(code); |
| 90 info()->CommitDependencies(code); | 90 info()->CommitDependencies(code); |
| 91 } | 91 } |
| 92 | 92 |
| 93 | 93 |
| 94 void LChunkBuilder::Abort(const char* reason) { | 94 void LChunkBuilder::Abort(BailoutReason reason) { |
| 95 info()->set_bailout_reason(reason); | 95 info()->set_bailout_reason(reason); |
| 96 status_ = ABORTED; | 96 status_ = ABORTED; |
| 97 } | 97 } |
| 98 | 98 |
| 99 | 99 |
| 100 void LCodeGen::Comment(const char* format, ...) { | 100 void LCodeGen::Comment(const char* format, ...) { |
| 101 if (!FLAG_code_comments) return; | 101 if (!FLAG_code_comments) return; |
| 102 char buffer[4 * KB]; | 102 char buffer[4 * KB]; |
| 103 StringBuilder builder(buffer, ARRAY_SIZE(buffer)); | 103 StringBuilder builder(buffer, ARRAY_SIZE(buffer)); |
| 104 va_list arguments; | 104 va_list arguments; |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 317 | 317 |
| 318 | 318 |
| 319 bool LCodeGen::GenerateDeoptJumpTable() { | 319 bool LCodeGen::GenerateDeoptJumpTable() { |
| 320 // Check that the jump table is accessible from everywhere in the function | 320 // Check that the jump table is accessible from everywhere in the function |
| 321 // code, i.e. that offsets to the table can be encoded in the 16bit signed | 321 // code, i.e. that offsets to the table can be encoded in the 16bit signed |
| 322 // immediate of a branch instruction. | 322 // immediate of a branch instruction. |
| 323 // To simplify we consider the code size from the first instruction to the | 323 // To simplify we consider the code size from the first instruction to the |
| 324 // end of the jump table. | 324 // end of the jump table. |
| 325 if (!is_int16((masm()->pc_offset() / Assembler::kInstrSize) + | 325 if (!is_int16((masm()->pc_offset() / Assembler::kInstrSize) + |
| 326 deopt_jump_table_.length() * 12)) { | 326 deopt_jump_table_.length() * 12)) { |
| 327 Abort("Generated code is too large"); | 327 Abort(kGeneratedCodeIsTooLarge); |
| 328 } | 328 } |
| 329 | 329 |
| 330 if (deopt_jump_table_.length() > 0) { | 330 if (deopt_jump_table_.length() > 0) { |
| 331 Comment(";;; -------------------- Jump table --------------------"); | 331 Comment(";;; -------------------- Jump table --------------------"); |
| 332 } | 332 } |
| 333 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); | 333 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_); |
| 334 Label table_start; | 334 Label table_start; |
| 335 __ bind(&table_start); | 335 __ bind(&table_start); |
| 336 Label needs_frame; | 336 Label needs_frame; |
| 337 for (int i = 0; i < deopt_jump_table_.length(); i++) { | 337 for (int i = 0; i < deopt_jump_table_.length(); i++) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 HConstant* constant = chunk_->LookupConstant(const_op); | 404 HConstant* constant = chunk_->LookupConstant(const_op); |
| 405 Handle<Object> literal = constant->handle(); | 405 Handle<Object> literal = constant->handle(); |
| 406 Representation r = chunk_->LookupLiteralRepresentation(const_op); | 406 Representation r = chunk_->LookupLiteralRepresentation(const_op); |
| 407 if (r.IsInteger32()) { | 407 if (r.IsInteger32()) { |
| 408 ASSERT(literal->IsNumber()); | 408 ASSERT(literal->IsNumber()); |
| 409 __ li(scratch, Operand(static_cast<int32_t>(literal->Number()))); | 409 __ li(scratch, Operand(static_cast<int32_t>(literal->Number()))); |
| 410 } else if (r.IsSmi()) { | 410 } else if (r.IsSmi()) { |
| 411 ASSERT(constant->HasSmiValue()); | 411 ASSERT(constant->HasSmiValue()); |
| 412 __ li(scratch, Operand(Smi::FromInt(constant->Integer32Value()))); | 412 __ li(scratch, Operand(Smi::FromInt(constant->Integer32Value()))); |
| 413 } else if (r.IsDouble()) { | 413 } else if (r.IsDouble()) { |
| 414 Abort("EmitLoadRegister: Unsupported double immediate."); | 414 Abort(kEmitLoadRegisterUnsupportedDoubleImmediate); |
| 415 } else { | 415 } else { |
| 416 ASSERT(r.IsTagged()); | 416 ASSERT(r.IsTagged()); |
| 417 __ LoadObject(scratch, literal); | 417 __ LoadObject(scratch, literal); |
| 418 } | 418 } |
| 419 return scratch; | 419 return scratch; |
| 420 } else if (op->IsStackSlot() || op->IsArgument()) { | 420 } else if (op->IsStackSlot() || op->IsArgument()) { |
| 421 __ lw(scratch, ToMemOperand(op)); | 421 __ lw(scratch, ToMemOperand(op)); |
| 422 return scratch; | 422 return scratch; |
| 423 } | 423 } |
| 424 UNREACHABLE(); | 424 UNREACHABLE(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 442 HConstant* constant = chunk_->LookupConstant(const_op); | 442 HConstant* constant = chunk_->LookupConstant(const_op); |
| 443 Handle<Object> literal = constant->handle(); | 443 Handle<Object> literal = constant->handle(); |
| 444 Representation r = chunk_->LookupLiteralRepresentation(const_op); | 444 Representation r = chunk_->LookupLiteralRepresentation(const_op); |
| 445 if (r.IsInteger32()) { | 445 if (r.IsInteger32()) { |
| 446 ASSERT(literal->IsNumber()); | 446 ASSERT(literal->IsNumber()); |
| 447 __ li(at, Operand(static_cast<int32_t>(literal->Number()))); | 447 __ li(at, Operand(static_cast<int32_t>(literal->Number()))); |
| 448 __ mtc1(at, flt_scratch); | 448 __ mtc1(at, flt_scratch); |
| 449 __ cvt_d_w(dbl_scratch, flt_scratch); | 449 __ cvt_d_w(dbl_scratch, flt_scratch); |
| 450 return dbl_scratch; | 450 return dbl_scratch; |
| 451 } else if (r.IsDouble()) { | 451 } else if (r.IsDouble()) { |
| 452 Abort("unsupported double immediate"); | 452 Abort(kUnsupportedDoubleImmediate); |
| 453 } else if (r.IsTagged()) { | 453 } else if (r.IsTagged()) { |
| 454 Abort("unsupported tagged immediate"); | 454 Abort(kUnsupportedTaggedImmediate); |
| 455 } | 455 } |
| 456 } else if (op->IsStackSlot() || op->IsArgument()) { | 456 } else if (op->IsStackSlot() || op->IsArgument()) { |
| 457 MemOperand mem_op = ToMemOperand(op); | 457 MemOperand mem_op = ToMemOperand(op); |
| 458 __ ldc1(dbl_scratch, mem_op); | 458 __ ldc1(dbl_scratch, mem_op); |
| 459 return dbl_scratch; | 459 return dbl_scratch; |
| 460 } | 460 } |
| 461 UNREACHABLE(); | 461 UNREACHABLE(); |
| 462 return dbl_scratch; | 462 return dbl_scratch; |
| 463 } | 463 } |
| 464 | 464 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 LConstantOperand* const_op = LConstantOperand::cast(op); | 513 LConstantOperand* const_op = LConstantOperand::cast(op); |
| 514 HConstant* constant = chunk()->LookupConstant(const_op); | 514 HConstant* constant = chunk()->LookupConstant(const_op); |
| 515 Representation r = chunk_->LookupLiteralRepresentation(const_op); | 515 Representation r = chunk_->LookupLiteralRepresentation(const_op); |
| 516 if (r.IsSmi()) { | 516 if (r.IsSmi()) { |
| 517 ASSERT(constant->HasSmiValue()); | 517 ASSERT(constant->HasSmiValue()); |
| 518 return Operand(Smi::FromInt(constant->Integer32Value())); | 518 return Operand(Smi::FromInt(constant->Integer32Value())); |
| 519 } else if (r.IsInteger32()) { | 519 } else if (r.IsInteger32()) { |
| 520 ASSERT(constant->HasInteger32Value()); | 520 ASSERT(constant->HasInteger32Value()); |
| 521 return Operand(constant->Integer32Value()); | 521 return Operand(constant->Integer32Value()); |
| 522 } else if (r.IsDouble()) { | 522 } else if (r.IsDouble()) { |
| 523 Abort("ToOperand Unsupported double immediate."); | 523 Abort(kToOperandUnsupportedDoubleImmediate); |
| 524 } | 524 } |
| 525 ASSERT(r.IsTagged()); | 525 ASSERT(r.IsTagged()); |
| 526 return Operand(constant->handle()); | 526 return Operand(constant->handle()); |
| 527 } else if (op->IsRegister()) { | 527 } else if (op->IsRegister()) { |
| 528 return Operand(ToRegister(op)); | 528 return Operand(ToRegister(op)); |
| 529 } else if (op->IsDoubleRegister()) { | 529 } else if (op->IsDoubleRegister()) { |
| 530 Abort("ToOperand IsDoubleRegister unimplemented"); | 530 Abort(kToOperandIsDoubleRegisterUnimplemented); |
| 531 return Operand(0); | 531 return Operand(0); |
| 532 } | 532 } |
| 533 // Stack slots not implemented, use ToMemOperand instead. | 533 // Stack slots not implemented, use ToMemOperand instead. |
| 534 UNREACHABLE(); | 534 UNREACHABLE(); |
| 535 return Operand(0); | 535 return Operand(0); |
| 536 } | 536 } |
| 537 | 537 |
| 538 | 538 |
| 539 MemOperand LCodeGen::ToMemOperand(LOperand* op) const { | 539 MemOperand LCodeGen::ToMemOperand(LOperand* op) const { |
| 540 ASSERT(!op->IsRegister()); | 540 ASSERT(!op->IsRegister()); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 Deoptimizer::BailoutType bailout_type, | 741 Deoptimizer::BailoutType bailout_type, |
| 742 Register src1, | 742 Register src1, |
| 743 const Operand& src2) { | 743 const Operand& src2) { |
| 744 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); | 744 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); |
| 745 ASSERT(environment->HasBeenRegistered()); | 745 ASSERT(environment->HasBeenRegistered()); |
| 746 int id = environment->deoptimization_index(); | 746 int id = environment->deoptimization_index(); |
| 747 ASSERT(info()->IsOptimizing() || info()->IsStub()); | 747 ASSERT(info()->IsOptimizing() || info()->IsStub()); |
| 748 Address entry = | 748 Address entry = |
| 749 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); | 749 Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); |
| 750 if (entry == NULL) { | 750 if (entry == NULL) { |
| 751 Abort("bailout was not prepared"); | 751 Abort(kBailoutWasNotPrepared); |
| 752 return; | 752 return; |
| 753 } | 753 } |
| 754 | 754 |
| 755 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on MIPS. | 755 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on MIPS. |
| 756 if (FLAG_deopt_every_n_times == 1 && | 756 if (FLAG_deopt_every_n_times == 1 && |
| 757 !info()->IsStub() && | 757 !info()->IsStub() && |
| 758 info()->opt_count() == id) { | 758 info()->opt_count() == id) { |
| 759 ASSERT(frame_is_built_); | 759 ASSERT(frame_is_built_); |
| 760 __ Call(entry, RelocInfo::RUNTIME_ENTRY); | 760 __ Call(entry, RelocInfo::RUNTIME_ENTRY); |
| 761 return; | 761 return; |
| (...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1576 __ And(at, left, Operand(0x80000000)); | 1576 __ And(at, left, Operand(0x80000000)); |
| 1577 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); | 1577 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); |
| 1578 } | 1578 } |
| 1579 __ Move(result, left); | 1579 __ Move(result, left); |
| 1580 } | 1580 } |
| 1581 break; | 1581 break; |
| 1582 case Token::SHL: | 1582 case Token::SHL: |
| 1583 if (shift_count != 0) { | 1583 if (shift_count != 0) { |
| 1584 if (instr->hydrogen_value()->representation().IsSmi() && | 1584 if (instr->hydrogen_value()->representation().IsSmi() && |
| 1585 instr->can_deopt()) { | 1585 instr->can_deopt()) { |
| 1586 __ sll(result, left, shift_count - 1); | 1586 if (shift_count != 1) { |
| 1587 __ SmiTagCheckOverflow(result, result, scratch); | 1587 __ sll(result, left, shift_count - 1); |
| 1588 __ SmiTagCheckOverflow(result, result, scratch); |
| 1589 } else { |
| 1590 __ SmiTagCheckOverflow(result, left, scratch); |
| 1591 } |
| 1588 DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg)); | 1592 DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg)); |
| 1589 } else { | 1593 } else { |
| 1590 __ sll(result, left, shift_count); | 1594 __ sll(result, left, shift_count); |
| 1591 } | 1595 } |
| 1592 } else { | 1596 } else { |
| 1593 __ Move(result, left); | 1597 __ Move(result, left); |
| 1594 } | 1598 } |
| 1595 break; | 1599 break; |
| 1596 default: | 1600 default: |
| 1597 UNREACHABLE(); | 1601 UNREACHABLE(); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1651 | 1655 |
| 1652 | 1656 |
| 1653 void LCodeGen::DoConstantD(LConstantD* instr) { | 1657 void LCodeGen::DoConstantD(LConstantD* instr) { |
| 1654 ASSERT(instr->result()->IsDoubleRegister()); | 1658 ASSERT(instr->result()->IsDoubleRegister()); |
| 1655 DoubleRegister result = ToDoubleRegister(instr->result()); | 1659 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 1656 double v = instr->value(); | 1660 double v = instr->value(); |
| 1657 __ Move(result, v); | 1661 __ Move(result, v); |
| 1658 } | 1662 } |
| 1659 | 1663 |
| 1660 | 1664 |
| 1665 void LCodeGen::DoConstantE(LConstantE* instr) { |
| 1666 __ li(ToRegister(instr->result()), Operand(instr->value())); |
| 1667 } |
| 1668 |
| 1669 |
| 1661 void LCodeGen::DoConstantT(LConstantT* instr) { | 1670 void LCodeGen::DoConstantT(LConstantT* instr) { |
| 1662 Handle<Object> value = instr->value(); | 1671 Handle<Object> value = instr->value(); |
| 1663 AllowDeferredHandleDereference smi_check; | 1672 AllowDeferredHandleDereference smi_check; |
| 1664 __ LoadObject(ToRegister(instr->result()), value); | 1673 __ LoadObject(ToRegister(instr->result()), value); |
| 1665 } | 1674 } |
| 1666 | 1675 |
| 1667 | 1676 |
| 1668 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { | 1677 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { |
| 1669 Register result = ToRegister(instr->result()); | 1678 Register result = ToRegister(instr->result()); |
| 1670 Register map = ToRegister(instr->value()); | 1679 Register map = ToRegister(instr->value()); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1754 | 1763 |
| 1755 if (FLAG_debug_code) { | 1764 if (FLAG_debug_code) { |
| 1756 __ lw(at, FieldMemOperand(string, HeapObject::kMapOffset)); | 1765 __ lw(at, FieldMemOperand(string, HeapObject::kMapOffset)); |
| 1757 __ lbu(at, FieldMemOperand(at, Map::kInstanceTypeOffset)); | 1766 __ lbu(at, FieldMemOperand(at, Map::kInstanceTypeOffset)); |
| 1758 | 1767 |
| 1759 __ And(at, at, Operand(kStringRepresentationMask | kStringEncodingMask)); | 1768 __ And(at, at, Operand(kStringRepresentationMask | kStringEncodingMask)); |
| 1760 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; | 1769 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; |
| 1761 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; | 1770 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; |
| 1762 __ Subu(at, at, Operand(encoding == String::ONE_BYTE_ENCODING | 1771 __ Subu(at, at, Operand(encoding == String::ONE_BYTE_ENCODING |
| 1763 ? one_byte_seq_type : two_byte_seq_type)); | 1772 ? one_byte_seq_type : two_byte_seq_type)); |
| 1764 __ Check(eq, "Unexpected string type", at, Operand(zero_reg)); | 1773 __ Check(eq, kUnexpectedStringType, at, Operand(zero_reg)); |
| 1765 } | 1774 } |
| 1766 | 1775 |
| 1767 __ Addu(scratch, | 1776 __ Addu(scratch, |
| 1768 string, | 1777 string, |
| 1769 Operand(SeqString::kHeaderSize - kHeapObjectTag)); | 1778 Operand(SeqString::kHeaderSize - kHeapObjectTag)); |
| 1770 if (encoding == String::ONE_BYTE_ENCODING) { | 1779 if (encoding == String::ONE_BYTE_ENCODING) { |
| 1771 __ Addu(at, scratch, index); | 1780 __ Addu(at, scratch, index); |
| 1772 __ sb(value, MemOperand(at)); | 1781 __ sb(value, MemOperand(at)); |
| 1773 } else { | 1782 } else { |
| 1774 __ sll(at, index, 1); | 1783 __ sll(at, index, 1); |
| (...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2796 ASSERT(ToRegister(instr->value()).is(a0)); | 2805 ASSERT(ToRegister(instr->value()).is(a0)); |
| 2797 | 2806 |
| 2798 __ li(a2, Operand(instr->name())); | 2807 __ li(a2, Operand(instr->name())); |
| 2799 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) | 2808 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) |
| 2800 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 2809 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 2801 : isolate()->builtins()->StoreIC_Initialize(); | 2810 : isolate()->builtins()->StoreIC_Initialize(); |
| 2802 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); | 2811 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); |
| 2803 } | 2812 } |
| 2804 | 2813 |
| 2805 | 2814 |
| 2806 void LCodeGen::DoLinkObjectInList(LLinkObjectInList* instr) { | |
| 2807 Register object = ToRegister(instr->object()); | |
| 2808 ExternalReference sites_list_address = instr->GetReference(isolate()); | |
| 2809 | |
| 2810 __ li(at, Operand(sites_list_address)); | |
| 2811 __ lw(at, MemOperand(at)); | |
| 2812 __ sw(at, FieldMemOperand(object, | |
| 2813 instr->hydrogen()->store_field().offset())); | |
| 2814 __ li(at, Operand(sites_list_address)); | |
| 2815 __ sw(object, MemOperand(at)); | |
| 2816 } | |
| 2817 | |
| 2818 | |
| 2819 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 2815 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
| 2820 Register context = ToRegister(instr->context()); | 2816 Register context = ToRegister(instr->context()); |
| 2821 Register result = ToRegister(instr->result()); | 2817 Register result = ToRegister(instr->result()); |
| 2822 | 2818 |
| 2823 __ lw(result, ContextOperand(context, instr->slot_index())); | 2819 __ lw(result, ContextOperand(context, instr->slot_index())); |
| 2824 if (instr->hydrogen()->RequiresHoleCheck()) { | 2820 if (instr->hydrogen()->RequiresHoleCheck()) { |
| 2825 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 2821 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
| 2826 | 2822 |
| 2827 if (instr->hydrogen()->DeoptimizesOnHole()) { | 2823 if (instr->hydrogen()->DeoptimizesOnHole()) { |
| 2828 DeoptimizeIf(eq, instr->environment(), result, Operand(at)); | 2824 DeoptimizeIf(eq, instr->environment(), result, Operand(at)); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2871 } | 2867 } |
| 2872 | 2868 |
| 2873 __ bind(&skip_assignment); | 2869 __ bind(&skip_assignment); |
| 2874 } | 2870 } |
| 2875 | 2871 |
| 2876 | 2872 |
| 2877 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { | 2873 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { |
| 2878 HObjectAccess access = instr->hydrogen()->access(); | 2874 HObjectAccess access = instr->hydrogen()->access(); |
| 2879 int offset = access.offset(); | 2875 int offset = access.offset(); |
| 2880 Register object = ToRegister(instr->object()); | 2876 Register object = ToRegister(instr->object()); |
| 2877 |
| 2878 if (access.IsExternalMemory()) { |
| 2879 Register result = ToRegister(instr->result()); |
| 2880 __ lw(result, MemOperand(object, offset)); |
| 2881 return; |
| 2882 } |
| 2883 |
| 2881 if (instr->hydrogen()->representation().IsDouble()) { | 2884 if (instr->hydrogen()->representation().IsDouble()) { |
| 2882 DoubleRegister result = ToDoubleRegister(instr->result()); | 2885 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 2883 __ ldc1(result, FieldMemOperand(object, offset)); | 2886 __ ldc1(result, FieldMemOperand(object, offset)); |
| 2884 return; | 2887 return; |
| 2885 } | 2888 } |
| 2886 | 2889 |
| 2887 Register result = ToRegister(instr->result()); | 2890 Register result = ToRegister(instr->result()); |
| 2888 if (access.IsInobject()) { | 2891 if (access.IsInobject()) { |
| 2889 __ lw(result, FieldMemOperand(object, offset)); | 2892 __ lw(result, FieldMemOperand(object, offset)); |
| 2890 } else { | 2893 } else { |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3066 | 3069 |
| 3067 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { | 3070 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { |
| 3068 Register external_pointer = ToRegister(instr->elements()); | 3071 Register external_pointer = ToRegister(instr->elements()); |
| 3069 Register key = no_reg; | 3072 Register key = no_reg; |
| 3070 ElementsKind elements_kind = instr->elements_kind(); | 3073 ElementsKind elements_kind = instr->elements_kind(); |
| 3071 bool key_is_constant = instr->key()->IsConstantOperand(); | 3074 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 3072 int constant_key = 0; | 3075 int constant_key = 0; |
| 3073 if (key_is_constant) { | 3076 if (key_is_constant) { |
| 3074 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3077 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 3075 if (constant_key & 0xF0000000) { | 3078 if (constant_key & 0xF0000000) { |
| 3076 Abort("array index constant value too big."); | 3079 Abort(kArrayIndexConstantValueTooBig); |
| 3077 } | 3080 } |
| 3078 } else { | 3081 } else { |
| 3079 key = ToRegister(instr->key()); | 3082 key = ToRegister(instr->key()); |
| 3080 } | 3083 } |
| 3081 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 3084 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 3082 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 3085 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 3083 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 3086 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 3084 int additional_offset = instr->additional_index() << element_size_shift; | 3087 int additional_offset = instr->additional_index() << element_size_shift; |
| 3085 | 3088 |
| 3086 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 3089 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3152 DoubleRegister result = ToDoubleRegister(instr->result()); | 3155 DoubleRegister result = ToDoubleRegister(instr->result()); |
| 3153 Register scratch = scratch0(); | 3156 Register scratch = scratch0(); |
| 3154 | 3157 |
| 3155 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | 3158 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
| 3156 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 3159 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 3157 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 3160 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 3158 int constant_key = 0; | 3161 int constant_key = 0; |
| 3159 if (key_is_constant) { | 3162 if (key_is_constant) { |
| 3160 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 3163 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 3161 if (constant_key & 0xF0000000) { | 3164 if (constant_key & 0xF0000000) { |
| 3162 Abort("array index constant value too big."); | 3165 Abort(kArrayIndexConstantValueTooBig); |
| 3163 } | 3166 } |
| 3164 } else { | 3167 } else { |
| 3165 key = ToRegister(instr->key()); | 3168 key = ToRegister(instr->key()); |
| 3166 } | 3169 } |
| 3167 | 3170 |
| 3168 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + | 3171 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + |
| 3169 ((constant_key + instr->additional_index()) << element_size_shift); | 3172 ((constant_key + instr->additional_index()) << element_size_shift); |
| 3170 if (!key_is_constant) { | 3173 if (!key_is_constant) { |
| 3171 __ sll(scratch, key, shift_size); | 3174 __ sll(scratch, key, shift_size); |
| 3172 __ Addu(elements, elements, scratch); | 3175 __ Addu(elements, elements, scratch); |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3423 ParameterCount actual(receiver); | 3426 ParameterCount actual(receiver); |
| 3424 __ InvokeFunction(function, actual, CALL_FUNCTION, | 3427 __ InvokeFunction(function, actual, CALL_FUNCTION, |
| 3425 safepoint_generator, CALL_AS_METHOD); | 3428 safepoint_generator, CALL_AS_METHOD); |
| 3426 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 3429 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 3427 } | 3430 } |
| 3428 | 3431 |
| 3429 | 3432 |
| 3430 void LCodeGen::DoPushArgument(LPushArgument* instr) { | 3433 void LCodeGen::DoPushArgument(LPushArgument* instr) { |
| 3431 LOperand* argument = instr->value(); | 3434 LOperand* argument = instr->value(); |
| 3432 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { | 3435 if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) { |
| 3433 Abort("DoPushArgument not implemented for double type."); | 3436 Abort(kDoPushArgumentNotImplementedForDoubleType); |
| 3434 } else { | 3437 } else { |
| 3435 Register argument_reg = EmitLoadRegister(argument, at); | 3438 Register argument_reg = EmitLoadRegister(argument, at); |
| 3436 __ push(argument_reg); | 3439 __ push(argument_reg); |
| 3437 } | 3440 } |
| 3438 } | 3441 } |
| 3439 | 3442 |
| 3440 | 3443 |
| 3441 void LCodeGen::DoDrop(LDrop* instr) { | 3444 void LCodeGen::DoDrop(LDrop* instr) { |
| 3442 __ Drop(instr->count()); | 3445 __ Drop(instr->count()); |
| 3443 } | 3446 } |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4108 | 4111 |
| 4109 | 4112 |
| 4110 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 4113 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
| 4111 Representation representation = instr->representation(); | 4114 Representation representation = instr->representation(); |
| 4112 | 4115 |
| 4113 Register object = ToRegister(instr->object()); | 4116 Register object = ToRegister(instr->object()); |
| 4114 Register scratch = scratch0(); | 4117 Register scratch = scratch0(); |
| 4115 HObjectAccess access = instr->hydrogen()->access(); | 4118 HObjectAccess access = instr->hydrogen()->access(); |
| 4116 int offset = access.offset(); | 4119 int offset = access.offset(); |
| 4117 | 4120 |
| 4121 if (access.IsExternalMemory()) { |
| 4122 Register value = ToRegister(instr->value()); |
| 4123 __ sw(value, MemOperand(object, offset)); |
| 4124 return; |
| 4125 } |
| 4126 |
| 4118 Handle<Map> transition = instr->transition(); | 4127 Handle<Map> transition = instr->transition(); |
| 4119 | 4128 |
| 4120 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | 4129 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
| 4121 Register value = ToRegister(instr->value()); | 4130 Register value = ToRegister(instr->value()); |
| 4122 if (!instr->hydrogen()->value()->type().IsHeapObject()) { | 4131 if (!instr->hydrogen()->value()->type().IsHeapObject()) { |
| 4123 __ And(scratch, value, Operand(kSmiTagMask)); | 4132 __ And(scratch, value, Operand(kSmiTagMask)); |
| 4124 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); | 4133 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); |
| 4125 } | 4134 } |
| 4126 } else if (FLAG_track_double_fields && representation.IsDouble()) { | 4135 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
| 4127 ASSERT(transition.is_null()); | 4136 ASSERT(transition.is_null()); |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4242 | 4251 |
| 4243 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { | 4252 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { |
| 4244 Register external_pointer = ToRegister(instr->elements()); | 4253 Register external_pointer = ToRegister(instr->elements()); |
| 4245 Register key = no_reg; | 4254 Register key = no_reg; |
| 4246 ElementsKind elements_kind = instr->elements_kind(); | 4255 ElementsKind elements_kind = instr->elements_kind(); |
| 4247 bool key_is_constant = instr->key()->IsConstantOperand(); | 4256 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 4248 int constant_key = 0; | 4257 int constant_key = 0; |
| 4249 if (key_is_constant) { | 4258 if (key_is_constant) { |
| 4250 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4259 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 4251 if (constant_key & 0xF0000000) { | 4260 if (constant_key & 0xF0000000) { |
| 4252 Abort("array index constant value too big."); | 4261 Abort(kArrayIndexConstantValueTooBig); |
| 4253 } | 4262 } |
| 4254 } else { | 4263 } else { |
| 4255 key = ToRegister(instr->key()); | 4264 key = ToRegister(instr->key()); |
| 4256 } | 4265 } |
| 4257 int element_size_shift = ElementsKindToShiftSize(elements_kind); | 4266 int element_size_shift = ElementsKindToShiftSize(elements_kind); |
| 4258 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4267 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 4259 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4268 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4260 int additional_offset = instr->additional_index() << element_size_shift; | 4269 int additional_offset = instr->additional_index() << element_size_shift; |
| 4261 | 4270 |
| 4262 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 4271 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4320 Register scratch = scratch0(); | 4329 Register scratch = scratch0(); |
| 4321 bool key_is_constant = instr->key()->IsConstantOperand(); | 4330 bool key_is_constant = instr->key()->IsConstantOperand(); |
| 4322 int constant_key = 0; | 4331 int constant_key = 0; |
| 4323 Label not_nan; | 4332 Label not_nan; |
| 4324 | 4333 |
| 4325 // Calculate the effective address of the slot in the array to store the | 4334 // Calculate the effective address of the slot in the array to store the |
| 4326 // double value. | 4335 // double value. |
| 4327 if (key_is_constant) { | 4336 if (key_is_constant) { |
| 4328 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); | 4337 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); |
| 4329 if (constant_key & 0xF0000000) { | 4338 if (constant_key & 0xF0000000) { |
| 4330 Abort("array index constant value too big."); | 4339 Abort(kArrayIndexConstantValueTooBig); |
| 4331 } | 4340 } |
| 4332 } else { | 4341 } else { |
| 4333 key = ToRegister(instr->key()); | 4342 key = ToRegister(instr->key()); |
| 4334 } | 4343 } |
| 4335 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); | 4344 int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); |
| 4336 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) | 4345 int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) |
| 4337 ? (element_size_shift - kSmiTagSize) : element_size_shift; | 4346 ? (element_size_shift - kSmiTagSize) : element_size_shift; |
| 4338 if (key_is_constant) { | 4347 if (key_is_constant) { |
| 4339 __ Addu(scratch, elements, Operand((constant_key << element_size_shift) + | 4348 __ Addu(scratch, elements, Operand((constant_key << element_size_shift) + |
| 4340 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); | 4349 FixedDoubleArray::kHeaderSize - kHeapObjectTag)); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4580 __ mov(result, zero_reg); | 4589 __ mov(result, zero_reg); |
| 4581 | 4590 |
| 4582 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 4591 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
| 4583 __ SmiTag(char_code); | 4592 __ SmiTag(char_code); |
| 4584 __ push(char_code); | 4593 __ push(char_code); |
| 4585 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr); | 4594 CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr); |
| 4586 __ StoreToSafepointRegisterSlot(v0, result); | 4595 __ StoreToSafepointRegisterSlot(v0, result); |
| 4587 } | 4596 } |
| 4588 | 4597 |
| 4589 | 4598 |
| 4590 void LCodeGen::DoStringLength(LStringLength* instr) { | |
| 4591 Register string = ToRegister(instr->string()); | |
| 4592 Register result = ToRegister(instr->result()); | |
| 4593 __ lw(result, FieldMemOperand(string, String::kLengthOffset)); | |
| 4594 } | |
| 4595 | |
| 4596 | |
| 4597 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { | 4599 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { |
| 4598 LOperand* input = instr->value(); | 4600 LOperand* input = instr->value(); |
| 4599 ASSERT(input->IsRegister() || input->IsStackSlot()); | 4601 ASSERT(input->IsRegister() || input->IsStackSlot()); |
| 4600 LOperand* output = instr->result(); | 4602 LOperand* output = instr->result(); |
| 4601 ASSERT(output->IsDoubleRegister()); | 4603 ASSERT(output->IsDoubleRegister()); |
| 4602 FPURegister single_scratch = double_scratch0().low(); | 4604 FPURegister single_scratch = double_scratch0().low(); |
| 4603 if (input->IsStackSlot()) { | 4605 if (input->IsStackSlot()) { |
| 4604 Register scratch = scratch0(); | 4606 Register scratch = scratch0(); |
| 4605 __ lw(scratch, ToMemOperand(input)); | 4607 __ lw(scratch, ToMemOperand(input)); |
| 4606 __ mtc1(scratch, single_scratch); | 4608 __ mtc1(scratch, single_scratch); |
| (...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5305 | 5307 |
| 5306 Register result = ToRegister(instr->result()); | 5308 Register result = ToRegister(instr->result()); |
| 5307 Register scratch = ToRegister(instr->temp1()); | 5309 Register scratch = ToRegister(instr->temp1()); |
| 5308 Register scratch2 = ToRegister(instr->temp2()); | 5310 Register scratch2 = ToRegister(instr->temp2()); |
| 5309 | 5311 |
| 5310 // Allocate memory for the object. | 5312 // Allocate memory for the object. |
| 5311 AllocationFlags flags = TAG_OBJECT; | 5313 AllocationFlags flags = TAG_OBJECT; |
| 5312 if (instr->hydrogen()->MustAllocateDoubleAligned()) { | 5314 if (instr->hydrogen()->MustAllocateDoubleAligned()) { |
| 5313 flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); | 5315 flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); |
| 5314 } | 5316 } |
| 5315 if (instr->hydrogen()->CanAllocateInOldPointerSpace()) { | 5317 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { |
| 5316 ASSERT(!instr->hydrogen()->CanAllocateInOldDataSpace()); | 5318 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); |
| 5319 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); |
| 5317 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE); | 5320 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE); |
| 5318 } else if (instr->hydrogen()->CanAllocateInOldDataSpace()) { | 5321 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { |
| 5322 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); |
| 5319 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE); | 5323 flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE); |
| 5320 } | 5324 } |
| 5321 if (instr->size()->IsConstantOperand()) { | 5325 if (instr->size()->IsConstantOperand()) { |
| 5322 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); | 5326 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); |
| 5323 __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags); | 5327 __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags); |
| 5324 } else { | 5328 } else { |
| 5325 Register size = ToRegister(instr->size()); | 5329 Register size = ToRegister(instr->size()); |
| 5326 __ Allocate(size, | 5330 __ Allocate(size, |
| 5327 result, | 5331 result, |
| 5328 scratch, | 5332 scratch, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5366 if (instr->size()->IsRegister()) { | 5370 if (instr->size()->IsRegister()) { |
| 5367 Register size = ToRegister(instr->size()); | 5371 Register size = ToRegister(instr->size()); |
| 5368 ASSERT(!size.is(result)); | 5372 ASSERT(!size.is(result)); |
| 5369 __ SmiTag(size); | 5373 __ SmiTag(size); |
| 5370 __ push(size); | 5374 __ push(size); |
| 5371 } else { | 5375 } else { |
| 5372 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); | 5376 int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); |
| 5373 __ Push(Smi::FromInt(size)); | 5377 __ Push(Smi::FromInt(size)); |
| 5374 } | 5378 } |
| 5375 | 5379 |
| 5376 if (instr->hydrogen()->CanAllocateInOldPointerSpace()) { | 5380 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { |
| 5377 ASSERT(!instr->hydrogen()->CanAllocateInOldDataSpace()); | 5381 ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); |
| 5382 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); |
| 5378 CallRuntimeFromDeferred(Runtime::kAllocateInOldPointerSpace, 1, instr); | 5383 CallRuntimeFromDeferred(Runtime::kAllocateInOldPointerSpace, 1, instr); |
| 5379 } else if (instr->hydrogen()->CanAllocateInOldDataSpace()) { | 5384 } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { |
| 5385 ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); |
| 5380 CallRuntimeFromDeferred(Runtime::kAllocateInOldDataSpace, 1, instr); | 5386 CallRuntimeFromDeferred(Runtime::kAllocateInOldDataSpace, 1, instr); |
| 5381 } else { | 5387 } else { |
| 5382 CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); | 5388 CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr); |
| 5383 } | 5389 } |
| 5384 __ StoreToSafepointRegisterSlot(v0, result); | 5390 __ StoreToSafepointRegisterSlot(v0, result); |
| 5385 } | 5391 } |
| 5386 | 5392 |
| 5387 | 5393 |
| 5388 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { | 5394 void LCodeGen::DoToFastProperties(LToFastProperties* instr) { |
| 5389 ASSERT(ToRegister(instr->value()).is(a0)); | 5395 ASSERT(ToRegister(instr->value()).is(a0)); |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5836 __ Subu(scratch, result, scratch); | 5842 __ Subu(scratch, result, scratch); |
| 5837 __ lw(result, FieldMemOperand(scratch, | 5843 __ lw(result, FieldMemOperand(scratch, |
| 5838 FixedArray::kHeaderSize - kPointerSize)); | 5844 FixedArray::kHeaderSize - kPointerSize)); |
| 5839 __ bind(&done); | 5845 __ bind(&done); |
| 5840 } | 5846 } |
| 5841 | 5847 |
| 5842 | 5848 |
| 5843 #undef __ | 5849 #undef __ |
| 5844 | 5850 |
| 5845 } } // namespace v8::internal | 5851 } } // namespace v8::internal |
| OLD | NEW |