| 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 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 // r1: Callee's JS function. | 114 // r1: Callee's JS function. |
| 115 // cp: Callee's context. | 115 // cp: Callee's context. |
| 116 // fp: Caller's frame pointer. | 116 // fp: Caller's frame pointer. |
| 117 // lr: Caller's pc. | 117 // lr: Caller's pc. |
| 118 | 118 |
| 119 // Strict mode functions and builtins need to replace the receiver | 119 // Strict mode functions and builtins need to replace the receiver |
| 120 // with undefined when called as functions (without an explicit | 120 // with undefined when called as functions (without an explicit |
| 121 // receiver object). r5 is zero for method calls and non-zero for | 121 // receiver object). r5 is zero for method calls and non-zero for |
| 122 // function calls. | 122 // function calls. |
| 123 if (!info_->is_classic_mode() || info_->is_native()) { | 123 if (!info_->is_classic_mode() || info_->is_native()) { |
| 124 Label ok; | |
| 125 __ cmp(r5, Operand::Zero()); | 124 __ cmp(r5, Operand::Zero()); |
| 126 __ b(eq, &ok); | |
| 127 int receiver_offset = scope()->num_parameters() * kPointerSize; | 125 int receiver_offset = scope()->num_parameters() * kPointerSize; |
| 128 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 126 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
| 129 __ str(r2, MemOperand(sp, receiver_offset)); | 127 __ str(r2, MemOperand(sp, receiver_offset), ne); |
| 130 __ bind(&ok); | |
| 131 } | 128 } |
| 132 } | 129 } |
| 133 | 130 |
| 134 info()->set_prologue_offset(masm_->pc_offset()); | 131 info()->set_prologue_offset(masm_->pc_offset()); |
| 135 if (NeedsEagerFrame()) { | 132 if (NeedsEagerFrame()) { |
| 136 if (info()->IsStub()) { | 133 __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME); |
| 137 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit()); | |
| 138 __ Push(Smi::FromInt(StackFrame::STUB)); | |
| 139 // Adjust FP to point to saved FP. | |
| 140 __ add(fp, sp, Operand(2 * kPointerSize)); | |
| 141 } else { | |
| 142 PredictableCodeSizeScope predictible_code_size_scope( | |
| 143 masm_, kNoCodeAgeSequenceLength * Assembler::kInstrSize); | |
| 144 // The following three instructions must remain together and unmodified | |
| 145 // for code aging to work properly. | |
| 146 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); | |
| 147 __ nop(ip.code()); | |
| 148 // Adjust FP to point to saved FP. | |
| 149 __ add(fp, sp, Operand(2 * kPointerSize)); | |
| 150 } | |
| 151 frame_is_built_ = true; | 134 frame_is_built_ = true; |
| 152 info_->AddNoFrameRange(0, masm_->pc_offset()); | 135 info_->AddNoFrameRange(0, masm_->pc_offset()); |
| 153 } | 136 } |
| 154 | 137 |
| 155 // Reserve space for the stack slots needed by the code. | 138 // Reserve space for the stack slots needed by the code. |
| 156 int slots = GetStackSlotCount(); | 139 int slots = GetStackSlotCount(); |
| 157 if (slots > 0) { | 140 if (slots > 0) { |
| 158 if (FLAG_debug_code) { | 141 if (FLAG_debug_code) { |
| 159 __ sub(sp, sp, Operand(slots * kPointerSize)); | 142 __ sub(sp, sp, Operand(slots * kPointerSize)); |
| 160 __ push(r0); | 143 __ push(r0); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 __ sub(sp, sp, Operand(slots * kPointerSize)); | 235 __ sub(sp, sp, Operand(slots * kPointerSize)); |
| 253 } | 236 } |
| 254 | 237 |
| 255 | 238 |
| 256 bool LCodeGen::GenerateDeferredCode() { | 239 bool LCodeGen::GenerateDeferredCode() { |
| 257 ASSERT(is_generating()); | 240 ASSERT(is_generating()); |
| 258 if (deferred_.length() > 0) { | 241 if (deferred_.length() > 0) { |
| 259 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { | 242 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { |
| 260 LDeferredCode* code = deferred_[i]; | 243 LDeferredCode* code = deferred_[i]; |
| 261 | 244 |
| 262 int pos = instructions_->at(code->instruction_index())->position(); | 245 HValue* value = |
| 263 RecordAndUpdatePosition(pos); | 246 instructions_->at(code->instruction_index())->hydrogen_value(); |
| 247 RecordAndWritePosition(value->position()); |
| 264 | 248 |
| 265 Comment(";;; <@%d,#%d> " | 249 Comment(";;; <@%d,#%d> " |
| 266 "-------------------- Deferred %s --------------------", | 250 "-------------------- Deferred %s --------------------", |
| 267 code->instruction_index(), | 251 code->instruction_index(), |
| 268 code->instr()->hydrogen_value()->id(), | 252 code->instr()->hydrogen_value()->id(), |
| 269 code->instr()->Mnemonic()); | 253 code->instr()->Mnemonic()); |
| 270 __ bind(code->entry()); | 254 __ bind(code->entry()); |
| 271 if (NeedsDeferredFrame()) { | 255 if (NeedsDeferredFrame()) { |
| 272 Comment(";;; Build frame"); | 256 Comment(";;; Build frame"); |
| 273 ASSERT(!frame_is_built_); | 257 ASSERT(!frame_is_built_); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 HConstant* constant = chunk_->LookupConstant(const_op); | 378 HConstant* constant = chunk_->LookupConstant(const_op); |
| 395 Handle<Object> literal = constant->handle(isolate()); | 379 Handle<Object> literal = constant->handle(isolate()); |
| 396 Representation r = chunk_->LookupLiteralRepresentation(const_op); | 380 Representation r = chunk_->LookupLiteralRepresentation(const_op); |
| 397 if (r.IsInteger32()) { | 381 if (r.IsInteger32()) { |
| 398 ASSERT(literal->IsNumber()); | 382 ASSERT(literal->IsNumber()); |
| 399 __ mov(scratch, Operand(static_cast<int32_t>(literal->Number()))); | 383 __ mov(scratch, Operand(static_cast<int32_t>(literal->Number()))); |
| 400 } else if (r.IsDouble()) { | 384 } else if (r.IsDouble()) { |
| 401 Abort(kEmitLoadRegisterUnsupportedDoubleImmediate); | 385 Abort(kEmitLoadRegisterUnsupportedDoubleImmediate); |
| 402 } else { | 386 } else { |
| 403 ASSERT(r.IsSmiOrTagged()); | 387 ASSERT(r.IsSmiOrTagged()); |
| 404 __ LoadObject(scratch, literal); | 388 __ Move(scratch, literal); |
| 405 } | 389 } |
| 406 return scratch; | 390 return scratch; |
| 407 } else if (op->IsStackSlot() || op->IsArgument()) { | 391 } else if (op->IsStackSlot() || op->IsArgument()) { |
| 408 __ ldr(scratch, ToMemOperand(op)); | 392 __ ldr(scratch, ToMemOperand(op)); |
| 409 return scratch; | 393 return scratch; |
| 410 } | 394 } |
| 411 UNREACHABLE(); | 395 UNREACHABLE(); |
| 412 return scratch; | 396 return scratch; |
| 413 } | 397 } |
| 414 | 398 |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 void LCodeGen::CallCodeGeneric(Handle<Code> code, | 662 void LCodeGen::CallCodeGeneric(Handle<Code> code, |
| 679 RelocInfo::Mode mode, | 663 RelocInfo::Mode mode, |
| 680 LInstruction* instr, | 664 LInstruction* instr, |
| 681 SafepointMode safepoint_mode, | 665 SafepointMode safepoint_mode, |
| 682 TargetAddressStorageMode storage_mode) { | 666 TargetAddressStorageMode storage_mode) { |
| 683 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); | 667 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); |
| 684 ASSERT(instr != NULL); | 668 ASSERT(instr != NULL); |
| 685 // Block literal pool emission to ensure nop indicating no inlined smi code | 669 // Block literal pool emission to ensure nop indicating no inlined smi code |
| 686 // is in the correct position. | 670 // is in the correct position. |
| 687 Assembler::BlockConstPoolScope block_const_pool(masm()); | 671 Assembler::BlockConstPoolScope block_const_pool(masm()); |
| 688 LPointerMap* pointers = instr->pointer_map(); | |
| 689 RecordPosition(pointers->position()); | |
| 690 __ Call(code, mode, TypeFeedbackId::None(), al, storage_mode); | 672 __ Call(code, mode, TypeFeedbackId::None(), al, storage_mode); |
| 691 RecordSafepointWithLazyDeopt(instr, safepoint_mode); | 673 RecordSafepointWithLazyDeopt(instr, safepoint_mode); |
| 692 | 674 |
| 693 // Signal that we don't inline smi code before these stubs in the | 675 // Signal that we don't inline smi code before these stubs in the |
| 694 // optimizing code generator. | 676 // optimizing code generator. |
| 695 if (code->kind() == Code::BINARY_OP_IC || | 677 if (code->kind() == Code::BINARY_OP_IC || |
| 696 code->kind() == Code::COMPARE_IC) { | 678 code->kind() == Code::COMPARE_IC) { |
| 697 __ nop(); | 679 __ nop(); |
| 698 } | 680 } |
| 699 } | 681 } |
| 700 | 682 |
| 701 | 683 |
| 702 void LCodeGen::CallRuntime(const Runtime::Function* function, | 684 void LCodeGen::CallRuntime(const Runtime::Function* function, |
| 703 int num_arguments, | 685 int num_arguments, |
| 704 LInstruction* instr, | 686 LInstruction* instr, |
| 705 SaveFPRegsMode save_doubles) { | 687 SaveFPRegsMode save_doubles) { |
| 706 ASSERT(instr != NULL); | 688 ASSERT(instr != NULL); |
| 707 LPointerMap* pointers = instr->pointer_map(); | |
| 708 ASSERT(pointers != NULL); | |
| 709 RecordPosition(pointers->position()); | |
| 710 | 689 |
| 711 __ CallRuntime(function, num_arguments, save_doubles); | 690 __ CallRuntime(function, num_arguments, save_doubles); |
| 712 | 691 |
| 713 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); | 692 RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT); |
| 714 } | 693 } |
| 715 | 694 |
| 716 | 695 |
| 717 void LCodeGen::LoadContextFromDeferred(LOperand* context) { | 696 void LCodeGen::LoadContextFromDeferred(LOperand* context) { |
| 718 if (context->IsRegister()) { | 697 if (context->IsRegister()) { |
| 719 __ Move(cp, ToRegister(context)); | 698 __ Move(cp, ToRegister(context)); |
| 720 } else if (context->IsStackSlot()) { | 699 } else if (context->IsStackSlot()) { |
| 721 __ ldr(cp, ToMemOperand(context)); | 700 __ ldr(cp, ToMemOperand(context)); |
| 722 } else if (context->IsConstantOperand()) { | 701 } else if (context->IsConstantOperand()) { |
| 723 HConstant* constant = | 702 HConstant* constant = |
| 724 chunk_->LookupConstant(LConstantOperand::cast(context)); | 703 chunk_->LookupConstant(LConstantOperand::cast(context)); |
| 725 __ LoadObject(cp, Handle<Object>::cast(constant->handle(isolate()))); | 704 __ Move(cp, Handle<Object>::cast(constant->handle(isolate()))); |
| 726 } else { | 705 } else { |
| 727 UNREACHABLE(); | 706 UNREACHABLE(); |
| 728 } | 707 } |
| 729 } | 708 } |
| 730 | 709 |
| 731 | 710 |
| 732 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, | 711 void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, |
| 733 int argc, | 712 int argc, |
| 734 LInstruction* instr, | 713 LInstruction* instr, |
| 735 LOperand* context) { | 714 LOperand* context) { |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 } | 936 } |
| 958 | 937 |
| 959 | 938 |
| 960 void LCodeGen::RecordSafepoint(LPointerMap* pointers, | 939 void LCodeGen::RecordSafepoint(LPointerMap* pointers, |
| 961 Safepoint::DeoptMode deopt_mode) { | 940 Safepoint::DeoptMode deopt_mode) { |
| 962 RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode); | 941 RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode); |
| 963 } | 942 } |
| 964 | 943 |
| 965 | 944 |
| 966 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) { | 945 void LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) { |
| 967 LPointerMap empty_pointers(RelocInfo::kNoPosition, zone()); | 946 LPointerMap empty_pointers(zone()); |
| 968 RecordSafepoint(&empty_pointers, deopt_mode); | 947 RecordSafepoint(&empty_pointers, deopt_mode); |
| 969 } | 948 } |
| 970 | 949 |
| 971 | 950 |
| 972 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, | 951 void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, |
| 973 int arguments, | 952 int arguments, |
| 974 Safepoint::DeoptMode deopt_mode) { | 953 Safepoint::DeoptMode deopt_mode) { |
| 975 RecordSafepoint( | 954 RecordSafepoint( |
| 976 pointers, Safepoint::kWithRegisters, arguments, deopt_mode); | 955 pointers, Safepoint::kWithRegisters, arguments, deopt_mode); |
| 977 } | 956 } |
| 978 | 957 |
| 979 | 958 |
| 980 void LCodeGen::RecordSafepointWithRegistersAndDoubles( | 959 void LCodeGen::RecordSafepointWithRegistersAndDoubles( |
| 981 LPointerMap* pointers, | 960 LPointerMap* pointers, |
| 982 int arguments, | 961 int arguments, |
| 983 Safepoint::DeoptMode deopt_mode) { | 962 Safepoint::DeoptMode deopt_mode) { |
| 984 RecordSafepoint( | 963 RecordSafepoint( |
| 985 pointers, Safepoint::kWithRegistersAndDoubles, arguments, deopt_mode); | 964 pointers, Safepoint::kWithRegistersAndDoubles, arguments, deopt_mode); |
| 986 } | 965 } |
| 987 | 966 |
| 988 | 967 |
| 989 void LCodeGen::RecordPosition(int position) { | 968 void LCodeGen::RecordAndWritePosition(int position) { |
| 990 if (position == RelocInfo::kNoPosition) return; | 969 if (position == RelocInfo::kNoPosition) return; |
| 991 masm()->positions_recorder()->RecordPosition(position); | 970 masm()->positions_recorder()->RecordPosition(position); |
| 971 masm()->positions_recorder()->WriteRecordedPositions(); |
| 992 } | 972 } |
| 993 | 973 |
| 994 | 974 |
| 995 void LCodeGen::RecordAndUpdatePosition(int position) { | |
| 996 if (position >= 0 && position != old_position_) { | |
| 997 masm()->positions_recorder()->RecordPosition(position); | |
| 998 old_position_ = position; | |
| 999 } | |
| 1000 } | |
| 1001 | |
| 1002 | |
| 1003 static const char* LabelType(LLabel* label) { | 975 static const char* LabelType(LLabel* label) { |
| 1004 if (label->is_loop_header()) return " (loop header)"; | 976 if (label->is_loop_header()) return " (loop header)"; |
| 1005 if (label->is_osr_entry()) return " (OSR entry)"; | 977 if (label->is_osr_entry()) return " (OSR entry)"; |
| 1006 return ""; | 978 return ""; |
| 1007 } | 979 } |
| 1008 | 980 |
| 1009 | 981 |
| 1010 void LCodeGen::DoLabel(LLabel* label) { | 982 void LCodeGen::DoLabel(LLabel* label) { |
| 1011 Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", | 983 Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------", |
| 1012 current_instruction_, | 984 current_instruction_, |
| (...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1858 | 1830 |
| 1859 | 1831 |
| 1860 void LCodeGen::DoConstantE(LConstantE* instr) { | 1832 void LCodeGen::DoConstantE(LConstantE* instr) { |
| 1861 __ mov(ToRegister(instr->result()), Operand(instr->value())); | 1833 __ mov(ToRegister(instr->result()), Operand(instr->value())); |
| 1862 } | 1834 } |
| 1863 | 1835 |
| 1864 | 1836 |
| 1865 void LCodeGen::DoConstantT(LConstantT* instr) { | 1837 void LCodeGen::DoConstantT(LConstantT* instr) { |
| 1866 Handle<Object> value = instr->value(isolate()); | 1838 Handle<Object> value = instr->value(isolate()); |
| 1867 AllowDeferredHandleDereference smi_check; | 1839 AllowDeferredHandleDereference smi_check; |
| 1868 __ LoadObject(ToRegister(instr->result()), value); | 1840 __ Move(ToRegister(instr->result()), value); |
| 1869 } | 1841 } |
| 1870 | 1842 |
| 1871 | 1843 |
| 1872 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { | 1844 void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) { |
| 1873 Register result = ToRegister(instr->result()); | 1845 Register result = ToRegister(instr->result()); |
| 1874 Register map = ToRegister(instr->value()); | 1846 Register map = ToRegister(instr->value()); |
| 1875 __ EnumLength(result, map); | 1847 __ EnumLength(result, map); |
| 1876 } | 1848 } |
| 1877 | 1849 |
| 1878 | 1850 |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2329 } | 2301 } |
| 2330 | 2302 |
| 2331 | 2303 |
| 2332 Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { | 2304 Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { |
| 2333 Condition cond = kNoCondition; | 2305 Condition cond = kNoCondition; |
| 2334 switch (op) { | 2306 switch (op) { |
| 2335 case Token::EQ: | 2307 case Token::EQ: |
| 2336 case Token::EQ_STRICT: | 2308 case Token::EQ_STRICT: |
| 2337 cond = eq; | 2309 cond = eq; |
| 2338 break; | 2310 break; |
| 2311 case Token::NE: |
| 2312 case Token::NE_STRICT: |
| 2313 cond = ne; |
| 2314 break; |
| 2339 case Token::LT: | 2315 case Token::LT: |
| 2340 cond = is_unsigned ? lo : lt; | 2316 cond = is_unsigned ? lo : lt; |
| 2341 break; | 2317 break; |
| 2342 case Token::GT: | 2318 case Token::GT: |
| 2343 cond = is_unsigned ? hi : gt; | 2319 cond = is_unsigned ? hi : gt; |
| 2344 break; | 2320 break; |
| 2345 case Token::LTE: | 2321 case Token::LTE: |
| 2346 cond = is_unsigned ? ls : le; | 2322 cond = is_unsigned ? ls : le; |
| 2347 break; | 2323 break; |
| 2348 case Token::GTE: | 2324 case Token::GTE: |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2811 InstanceofStub stub(flags); | 2787 InstanceofStub stub(flags); |
| 2812 | 2788 |
| 2813 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 2789 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
| 2814 LoadContextFromDeferred(instr->context()); | 2790 LoadContextFromDeferred(instr->context()); |
| 2815 | 2791 |
| 2816 // Get the temp register reserved by the instruction. This needs to be r4 as | 2792 // Get the temp register reserved by the instruction. This needs to be r4 as |
| 2817 // its slot of the pushing of safepoint registers is used to communicate the | 2793 // its slot of the pushing of safepoint registers is used to communicate the |
| 2818 // offset to the location of the map check. | 2794 // offset to the location of the map check. |
| 2819 Register temp = ToRegister(instr->temp()); | 2795 Register temp = ToRegister(instr->temp()); |
| 2820 ASSERT(temp.is(r4)); | 2796 ASSERT(temp.is(r4)); |
| 2821 __ LoadHeapObject(InstanceofStub::right(), instr->function()); | 2797 __ Move(InstanceofStub::right(), instr->function()); |
| 2822 static const int kAdditionalDelta = 5; | 2798 static const int kAdditionalDelta = 5; |
| 2823 // Make sure that code size is predicable, since we use specific constants | 2799 // Make sure that code size is predicable, since we use specific constants |
| 2824 // offsets in the code to find embedded values.. | 2800 // offsets in the code to find embedded values.. |
| 2825 PredictableCodeSizeScope predictable(masm_, 6 * Assembler::kInstrSize); | 2801 PredictableCodeSizeScope predictable(masm_, 6 * Assembler::kInstrSize); |
| 2826 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; | 2802 int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; |
| 2827 Label before_push_delta; | 2803 Label before_push_delta; |
| 2828 __ bind(&before_push_delta); | 2804 __ bind(&before_push_delta); |
| 2829 __ BlockConstPoolFor(kAdditionalDelta); | 2805 __ BlockConstPoolFor(kAdditionalDelta); |
| 2830 __ mov(temp, Operand(delta * kPointerSize)); | 2806 __ mov(temp, Operand(delta * kPointerSize)); |
| 2831 // The mov above can generate one or two instructions. The delta was computed | 2807 // The mov above can generate one or two instructions. The delta was computed |
| 2832 // for two instructions, so we need to pad here in case of one instruction. | 2808 // for two instructions, so we need to pad here in case of one instruction. |
| 2833 if (masm_->InstructionsGeneratedSince(&before_push_delta) != 2) { | 2809 if (masm_->InstructionsGeneratedSince(&before_push_delta) != 2) { |
| 2834 ASSERT_EQ(1, masm_->InstructionsGeneratedSince(&before_push_delta)); | 2810 ASSERT_EQ(1, masm_->InstructionsGeneratedSince(&before_push_delta)); |
| 2835 __ nop(); | 2811 __ nop(); |
| 2836 } | 2812 } |
| 2837 __ StoreToSafepointRegisterSlot(temp, temp); | 2813 __ StoreToSafepointRegisterSlot(temp, temp); |
| 2838 CallCodeGeneric(stub.GetCode(isolate()), | 2814 CallCodeGeneric(stub.GetCode(isolate()), |
| 2839 RelocInfo::CODE_TARGET, | 2815 RelocInfo::CODE_TARGET, |
| 2840 instr, | 2816 instr, |
| 2841 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); | 2817 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); |
| 2842 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); | 2818 LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment(); |
| 2843 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 2819 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |
| 2844 // Put the result value into the result register slot and | 2820 // Put the result value into the result register slot and |
| 2845 // restore all registers. | 2821 // restore all registers. |
| 2846 __ StoreToSafepointRegisterSlot(result, result); | 2822 __ StoreToSafepointRegisterSlot(result, result); |
| 2847 } | 2823 } |
| 2848 | 2824 |
| 2849 | 2825 |
| 2850 void LCodeGen::DoInstanceSize(LInstanceSize* instr) { | |
| 2851 Register object = ToRegister(instr->object()); | |
| 2852 Register result = ToRegister(instr->result()); | |
| 2853 __ ldr(result, FieldMemOperand(object, HeapObject::kMapOffset)); | |
| 2854 __ ldrb(result, FieldMemOperand(result, Map::kInstanceSizeOffset)); | |
| 2855 } | |
| 2856 | |
| 2857 | |
| 2858 void LCodeGen::DoCmpT(LCmpT* instr) { | 2826 void LCodeGen::DoCmpT(LCmpT* instr) { |
| 2859 ASSERT(ToRegister(instr->context()).is(cp)); | 2827 ASSERT(ToRegister(instr->context()).is(cp)); |
| 2860 Token::Value op = instr->op(); | 2828 Token::Value op = instr->op(); |
| 2861 | 2829 |
| 2862 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); | 2830 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); |
| 2863 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2831 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
| 2864 // This instruction also signals no smi code inlined. | 2832 // This instruction also signals no smi code inlined. |
| 2865 __ cmp(r0, Operand::Zero()); | 2833 __ cmp(r0, Operand::Zero()); |
| 2866 | 2834 |
| 2867 Condition condition = ComputeCompareCondition(op); | 2835 Condition condition = ComputeCompareCondition(op); |
| (...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3504 __ b(eq, &invoke); | 3472 __ b(eq, &invoke); |
| 3505 __ bind(&loop); | 3473 __ bind(&loop); |
| 3506 __ ldr(scratch, MemOperand(elements, length, LSL, 2)); | 3474 __ ldr(scratch, MemOperand(elements, length, LSL, 2)); |
| 3507 __ push(scratch); | 3475 __ push(scratch); |
| 3508 __ sub(length, length, Operand(1), SetCC); | 3476 __ sub(length, length, Operand(1), SetCC); |
| 3509 __ b(ne, &loop); | 3477 __ b(ne, &loop); |
| 3510 | 3478 |
| 3511 __ bind(&invoke); | 3479 __ bind(&invoke); |
| 3512 ASSERT(instr->HasPointerMap()); | 3480 ASSERT(instr->HasPointerMap()); |
| 3513 LPointerMap* pointers = instr->pointer_map(); | 3481 LPointerMap* pointers = instr->pointer_map(); |
| 3514 RecordPosition(pointers->position()); | |
| 3515 SafepointGenerator safepoint_generator( | 3482 SafepointGenerator safepoint_generator( |
| 3516 this, pointers, Safepoint::kLazyDeopt); | 3483 this, pointers, Safepoint::kLazyDeopt); |
| 3517 // The number of arguments is stored in receiver which is r0, as expected | 3484 // The number of arguments is stored in receiver which is r0, as expected |
| 3518 // by InvokeFunction. | 3485 // by InvokeFunction. |
| 3519 ParameterCount actual(receiver); | 3486 ParameterCount actual(receiver); |
| 3520 __ InvokeFunction(function, actual, CALL_FUNCTION, | 3487 __ InvokeFunction(function, actual, CALL_FUNCTION, |
| 3521 safepoint_generator, CALL_AS_METHOD); | 3488 safepoint_generator, CALL_AS_METHOD); |
| 3522 } | 3489 } |
| 3523 | 3490 |
| 3524 | 3491 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3560 Register context = ToRegister(instr->context()); | 3527 Register context = ToRegister(instr->context()); |
| 3561 Register result = ToRegister(instr->result()); | 3528 Register result = ToRegister(instr->result()); |
| 3562 __ ldr(result, | 3529 __ ldr(result, |
| 3563 MemOperand(context, Context::SlotOffset(Context::PREVIOUS_INDEX))); | 3530 MemOperand(context, Context::SlotOffset(Context::PREVIOUS_INDEX))); |
| 3564 } | 3531 } |
| 3565 | 3532 |
| 3566 | 3533 |
| 3567 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { | 3534 void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { |
| 3568 ASSERT(ToRegister(instr->context()).is(cp)); | 3535 ASSERT(ToRegister(instr->context()).is(cp)); |
| 3569 __ push(cp); // The context is the first argument. | 3536 __ push(cp); // The context is the first argument. |
| 3570 __ LoadHeapObject(scratch0(), instr->hydrogen()->pairs()); | 3537 __ Move(scratch0(), instr->hydrogen()->pairs()); |
| 3571 __ push(scratch0()); | 3538 __ push(scratch0()); |
| 3572 __ mov(scratch0(), Operand(Smi::FromInt(instr->hydrogen()->flags()))); | 3539 __ mov(scratch0(), Operand(Smi::FromInt(instr->hydrogen()->flags()))); |
| 3573 __ push(scratch0()); | 3540 __ push(scratch0()); |
| 3574 CallRuntime(Runtime::kDeclareGlobals, 3, instr); | 3541 CallRuntime(Runtime::kDeclareGlobals, 3, instr); |
| 3575 } | 3542 } |
| 3576 | 3543 |
| 3577 | 3544 |
| 3578 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { | 3545 void LCodeGen::DoGlobalObject(LGlobalObject* instr) { |
| 3579 Register context = ToRegister(instr->context()); | 3546 Register context = ToRegister(instr->context()); |
| 3580 Register result = ToRegister(instr->result()); | 3547 Register result = ToRegister(instr->result()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3594 int arity, | 3561 int arity, |
| 3595 LInstruction* instr, | 3562 LInstruction* instr, |
| 3596 CallKind call_kind, | 3563 CallKind call_kind, |
| 3597 R1State r1_state) { | 3564 R1State r1_state) { |
| 3598 bool dont_adapt_arguments = | 3565 bool dont_adapt_arguments = |
| 3599 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; | 3566 formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel; |
| 3600 bool can_invoke_directly = | 3567 bool can_invoke_directly = |
| 3601 dont_adapt_arguments || formal_parameter_count == arity; | 3568 dont_adapt_arguments || formal_parameter_count == arity; |
| 3602 | 3569 |
| 3603 LPointerMap* pointers = instr->pointer_map(); | 3570 LPointerMap* pointers = instr->pointer_map(); |
| 3604 RecordPosition(pointers->position()); | |
| 3605 | 3571 |
| 3606 if (can_invoke_directly) { | 3572 if (can_invoke_directly) { |
| 3607 if (r1_state == R1_UNINITIALIZED) { | 3573 if (r1_state == R1_UNINITIALIZED) { |
| 3608 __ LoadHeapObject(r1, function); | 3574 __ Move(r1, function); |
| 3609 } | 3575 } |
| 3610 | 3576 |
| 3611 // Change context. | 3577 // Change context. |
| 3612 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); | 3578 __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
| 3613 | 3579 |
| 3614 // Set r0 to arguments count if adaption is not needed. Assumes that r0 | 3580 // Set r0 to arguments count if adaption is not needed. Assumes that r0 |
| 3615 // is available to write to at this point. | 3581 // is available to write to at this point. |
| 3616 if (dont_adapt_arguments) { | 3582 if (dont_adapt_arguments) { |
| 3617 __ mov(r0, Operand(arity)); | 3583 __ mov(r0, Operand(arity)); |
| 3618 } | 3584 } |
| (...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4006 | 3972 |
| 4007 | 3973 |
| 4008 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { | 3974 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { |
| 4009 ASSERT(ToRegister(instr->context()).is(cp)); | 3975 ASSERT(ToRegister(instr->context()).is(cp)); |
| 4010 ASSERT(ToRegister(instr->function()).is(r1)); | 3976 ASSERT(ToRegister(instr->function()).is(r1)); |
| 4011 ASSERT(instr->HasPointerMap()); | 3977 ASSERT(instr->HasPointerMap()); |
| 4012 | 3978 |
| 4013 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); | 3979 Handle<JSFunction> known_function = instr->hydrogen()->known_function(); |
| 4014 if (known_function.is_null()) { | 3980 if (known_function.is_null()) { |
| 4015 LPointerMap* pointers = instr->pointer_map(); | 3981 LPointerMap* pointers = instr->pointer_map(); |
| 4016 RecordPosition(pointers->position()); | |
| 4017 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); | 3982 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); |
| 4018 ParameterCount count(instr->arity()); | 3983 ParameterCount count(instr->arity()); |
| 4019 __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); | 3984 __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); |
| 4020 } else { | 3985 } else { |
| 4021 CallKnownFunction(known_function, | 3986 CallKnownFunction(known_function, |
| 4022 instr->hydrogen()->formal_parameter_count(), | 3987 instr->hydrogen()->formal_parameter_count(), |
| 4023 instr->arity(), | 3988 instr->arity(), |
| 4024 instr, | 3989 instr, |
| 4025 CALL_AS_METHOD, | 3990 CALL_AS_METHOD, |
| 4026 R1_CONTAINS_TARGET); | 3991 R1_CONTAINS_TARGET); |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4537 RecordSafepointWithRegistersAndDoubles( | 4502 RecordSafepointWithRegistersAndDoubles( |
| 4538 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 4503 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
| 4539 } | 4504 } |
| 4540 __ bind(¬_applicable); | 4505 __ bind(¬_applicable); |
| 4541 } | 4506 } |
| 4542 | 4507 |
| 4543 | 4508 |
| 4544 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { | 4509 void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { |
| 4545 Register object = ToRegister(instr->object()); | 4510 Register object = ToRegister(instr->object()); |
| 4546 Register temp = ToRegister(instr->temp()); | 4511 Register temp = ToRegister(instr->temp()); |
| 4547 __ TestJSArrayForAllocationMemento(object, temp); | 4512 Label no_memento_found; |
| 4513 __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found); |
| 4548 DeoptimizeIf(eq, instr->environment()); | 4514 DeoptimizeIf(eq, instr->environment()); |
| 4515 __ bind(&no_memento_found); |
| 4549 } | 4516 } |
| 4550 | 4517 |
| 4551 | 4518 |
| 4552 void LCodeGen::DoStringAdd(LStringAdd* instr) { | 4519 void LCodeGen::DoStringAdd(LStringAdd* instr) { |
| 4553 ASSERT(ToRegister(instr->context()).is(cp)); | 4520 ASSERT(ToRegister(instr->context()).is(cp)); |
| 4554 __ push(ToRegister(instr->left())); | 4521 __ push(ToRegister(instr->left())); |
| 4555 __ push(ToRegister(instr->right())); | 4522 __ push(ToRegister(instr->right())); |
| 4556 StringAddStub stub(instr->hydrogen()->flags()); | 4523 StringAddStub stub(instr->hydrogen()->flags()); |
| 4557 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 4524 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
| 4558 } | 4525 } |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4676 __ vmov(single_scratch, scratch); | 4643 __ vmov(single_scratch, scratch); |
| 4677 } else { | 4644 } else { |
| 4678 __ vmov(single_scratch, ToRegister(input)); | 4645 __ vmov(single_scratch, ToRegister(input)); |
| 4679 } | 4646 } |
| 4680 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); | 4647 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); |
| 4681 } | 4648 } |
| 4682 | 4649 |
| 4683 | 4650 |
| 4684 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) { | 4651 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) { |
| 4685 LOperand* input = instr->value(); | 4652 LOperand* input = instr->value(); |
| 4686 ASSERT(input->IsRegister()); | |
| 4687 LOperand* output = instr->result(); | 4653 LOperand* output = instr->result(); |
| 4688 ASSERT(output->IsRegister()); | |
| 4689 __ SmiTag(ToRegister(output), ToRegister(input), SetCC); | 4654 __ SmiTag(ToRegister(output), ToRegister(input), SetCC); |
| 4690 if (!instr->hydrogen()->value()->HasRange() || | 4655 if (!instr->hydrogen()->value()->HasRange() || |
| 4691 !instr->hydrogen()->value()->range()->IsInSmiRange()) { | 4656 !instr->hydrogen()->value()->range()->IsInSmiRange()) { |
| 4692 DeoptimizeIf(vs, instr->environment()); | 4657 DeoptimizeIf(vs, instr->environment()); |
| 4693 } | 4658 } |
| 4694 } | 4659 } |
| 4695 | 4660 |
| 4696 | 4661 |
| 4697 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { | 4662 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { |
| 4698 LOperand* input = instr->value(); | 4663 LOperand* input = instr->value(); |
| 4699 LOperand* output = instr->result(); | 4664 LOperand* output = instr->result(); |
| 4700 | 4665 |
| 4701 SwVfpRegister flt_scratch = double_scratch0().low(); | 4666 SwVfpRegister flt_scratch = double_scratch0().low(); |
| 4702 __ vmov(flt_scratch, ToRegister(input)); | 4667 __ vmov(flt_scratch, ToRegister(input)); |
| 4703 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch); | 4668 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch); |
| 4704 } | 4669 } |
| 4705 | 4670 |
| 4706 | 4671 |
| 4672 void LCodeGen::DoUint32ToSmi(LUint32ToSmi* instr) { |
| 4673 LOperand* input = instr->value(); |
| 4674 LOperand* output = instr->result(); |
| 4675 if (!instr->hydrogen()->value()->HasRange() || |
| 4676 !instr->hydrogen()->value()->range()->IsInSmiRange()) { |
| 4677 __ tst(ToRegister(input), Operand(0xc0000000)); |
| 4678 DeoptimizeIf(ne, instr->environment()); |
| 4679 } |
| 4680 __ SmiTag(ToRegister(output), ToRegister(input)); |
| 4681 } |
| 4682 |
| 4683 |
| 4707 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 4684 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
| 4708 class DeferredNumberTagI V8_FINAL : public LDeferredCode { | 4685 class DeferredNumberTagI V8_FINAL : public LDeferredCode { |
| 4709 public: | 4686 public: |
| 4710 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) | 4687 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) |
| 4711 : LDeferredCode(codegen), instr_(instr) { } | 4688 : LDeferredCode(codegen), instr_(instr) { } |
| 4712 virtual void Generate() V8_OVERRIDE { | 4689 virtual void Generate() V8_OVERRIDE { |
| 4713 codegen()->DoDeferredNumberTagI(instr_, | 4690 codegen()->DoDeferredNumberTagI(instr_, |
| 4714 instr_->value(), | 4691 instr_->value(), |
| 4715 SIGNED_INT32); | 4692 SIGNED_INT32); |
| 4716 } | 4693 } |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4971 __ adc(scratch2, input_reg, Operand(input_reg)); | 4948 __ adc(scratch2, input_reg, Operand(input_reg)); |
| 4972 | 4949 |
| 4973 // Heap number map check. | 4950 // Heap number map check. |
| 4974 __ ldr(scratch1, FieldMemOperand(scratch2, HeapObject::kMapOffset)); | 4951 __ ldr(scratch1, FieldMemOperand(scratch2, HeapObject::kMapOffset)); |
| 4975 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 4952 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
| 4976 __ cmp(scratch1, Operand(ip)); | 4953 __ cmp(scratch1, Operand(ip)); |
| 4977 | 4954 |
| 4978 if (instr->truncating()) { | 4955 if (instr->truncating()) { |
| 4979 // Performs a truncating conversion of a floating point number as used by | 4956 // Performs a truncating conversion of a floating point number as used by |
| 4980 // the JS bitwise operations. | 4957 // the JS bitwise operations. |
| 4981 Label heap_number; | 4958 Label no_heap_number, check_bools, check_false; |
| 4982 __ b(eq, &heap_number); | 4959 __ b(ne, &no_heap_number); |
| 4983 // Check for undefined. Undefined is converted to zero for truncating | 4960 __ TruncateHeapNumberToI(input_reg, scratch2); |
| 4984 // conversions. | 4961 __ b(&done); |
| 4962 |
| 4963 // Check for Oddballs. Undefined/False is converted to zero and True to one |
| 4964 // for truncating conversions. |
| 4965 __ bind(&no_heap_number); |
| 4985 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 4966 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 4986 __ cmp(scratch2, Operand(ip)); | 4967 __ cmp(scratch2, Operand(ip)); |
| 4968 __ b(ne, &check_bools); |
| 4969 __ mov(input_reg, Operand::Zero()); |
| 4970 __ b(&done); |
| 4971 |
| 4972 __ bind(&check_bools); |
| 4973 __ LoadRoot(ip, Heap::kTrueValueRootIndex); |
| 4974 __ cmp(scratch2, Operand(ip)); |
| 4975 __ b(ne, &check_false); |
| 4976 __ mov(input_reg, Operand(1)); |
| 4977 __ b(&done); |
| 4978 |
| 4979 __ bind(&check_false); |
| 4980 __ LoadRoot(ip, Heap::kFalseValueRootIndex); |
| 4981 __ cmp(scratch2, Operand(ip)); |
| 4987 DeoptimizeIf(ne, instr->environment()); | 4982 DeoptimizeIf(ne, instr->environment()); |
| 4988 __ mov(input_reg, Operand::Zero()); | 4983 __ mov(input_reg, Operand::Zero()); |
| 4989 __ b(&done); | 4984 __ b(&done); |
| 4990 | |
| 4991 __ bind(&heap_number); | |
| 4992 __ TruncateHeapNumberToI(input_reg, scratch2); | |
| 4993 } else { | 4985 } else { |
| 4994 // Deoptimize if we don't have a heap number. | 4986 // Deoptimize if we don't have a heap number. |
| 4995 DeoptimizeIf(ne, instr->environment()); | 4987 DeoptimizeIf(ne, instr->environment()); |
| 4996 | 4988 |
| 4997 __ sub(ip, scratch2, Operand(kHeapObjectTag)); | 4989 __ sub(ip, scratch2, Operand(kHeapObjectTag)); |
| 4998 __ vldr(double_scratch2, ip, HeapNumber::kValueOffset); | 4990 __ vldr(double_scratch2, ip, HeapNumber::kValueOffset); |
| 4999 __ TryDoubleToInt32Exact(input_reg, double_scratch2, double_scratch); | 4991 __ TryDoubleToInt32Exact(input_reg, double_scratch2, double_scratch); |
| 5000 DeoptimizeIf(ne, instr->environment()); | 4992 DeoptimizeIf(ne, instr->environment()); |
| 5001 | 4993 |
| 5002 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 4994 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5429 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { | 5421 void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { |
| 5430 ASSERT(ToRegister(instr->context()).is(cp)); | 5422 ASSERT(ToRegister(instr->context()).is(cp)); |
| 5431 Label materialized; | 5423 Label materialized; |
| 5432 // Registers will be used as follows: | 5424 // Registers will be used as follows: |
| 5433 // r6 = literals array. | 5425 // r6 = literals array. |
| 5434 // r1 = regexp literal. | 5426 // r1 = regexp literal. |
| 5435 // r0 = regexp literal clone. | 5427 // r0 = regexp literal clone. |
| 5436 // r2-5 are used as temporaries. | 5428 // r2-5 are used as temporaries. |
| 5437 int literal_offset = | 5429 int literal_offset = |
| 5438 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); | 5430 FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index()); |
| 5439 __ LoadHeapObject(r6, instr->hydrogen()->literals()); | 5431 __ Move(r6, instr->hydrogen()->literals()); |
| 5440 __ ldr(r1, FieldMemOperand(r6, literal_offset)); | 5432 __ ldr(r1, FieldMemOperand(r6, literal_offset)); |
| 5441 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); | 5433 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); |
| 5442 __ cmp(r1, ip); | 5434 __ cmp(r1, ip); |
| 5443 __ b(ne, &materialized); | 5435 __ b(ne, &materialized); |
| 5444 | 5436 |
| 5445 // Create regexp literal using runtime function | 5437 // Create regexp literal using runtime function |
| 5446 // Result will be in r0. | 5438 // Result will be in r0. |
| 5447 __ mov(r5, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); | 5439 __ mov(r5, Operand(Smi::FromInt(instr->hydrogen()->literal_index()))); |
| 5448 __ mov(r4, Operand(instr->hydrogen()->pattern())); | 5440 __ mov(r4, Operand(instr->hydrogen()->pattern())); |
| 5449 __ mov(r3, Operand(instr->hydrogen()->flags())); | 5441 __ mov(r3, Operand(instr->hydrogen()->flags())); |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5834 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5826 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
| 5835 __ ldr(result, FieldMemOperand(scratch, | 5827 __ ldr(result, FieldMemOperand(scratch, |
| 5836 FixedArray::kHeaderSize - kPointerSize)); | 5828 FixedArray::kHeaderSize - kPointerSize)); |
| 5837 __ bind(&done); | 5829 __ bind(&done); |
| 5838 } | 5830 } |
| 5839 | 5831 |
| 5840 | 5832 |
| 5841 #undef __ | 5833 #undef __ |
| 5842 | 5834 |
| 5843 } } // namespace v8::internal | 5835 } } // namespace v8::internal |
| OLD | NEW |