| 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 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 // Always emit a 'return undefined' in case control fell off the end of | 304 // Always emit a 'return undefined' in case control fell off the end of |
| 305 // the body. | 305 // the body. |
| 306 { Comment cmnt(masm_, "[ return <undefined>;"); | 306 { Comment cmnt(masm_, "[ return <undefined>;"); |
| 307 __ mov(eax, isolate()->factory()->undefined_value()); | 307 __ mov(eax, isolate()->factory()->undefined_value()); |
| 308 EmitReturnSequence(); | 308 EmitReturnSequence(); |
| 309 } | 309 } |
| 310 } | 310 } |
| 311 | 311 |
| 312 | 312 |
| 313 void FullCodeGenerator::ClearAccumulator() { | 313 void FullCodeGenerator::ClearAccumulator() { |
| 314 __ Set(eax, Immediate(Smi::FromInt(0))); | 314 __ Move(eax, Immediate(Smi::FromInt(0))); |
| 315 } | 315 } |
| 316 | 316 |
| 317 | 317 |
| 318 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { | 318 void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) { |
| 319 __ mov(ebx, Immediate(profiling_counter_)); | 319 __ mov(ebx, Immediate(profiling_counter_)); |
| 320 __ sub(FieldOperand(ebx, Cell::kValueOffset), | 320 __ sub(FieldOperand(ebx, Cell::kValueOffset), |
| 321 Immediate(Smi::FromInt(delta))); | 321 Immediate(Smi::FromInt(delta))); |
| 322 } | 322 } |
| 323 | 323 |
| 324 | 324 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 463 } | 463 } |
| 464 | 464 |
| 465 | 465 |
| 466 void FullCodeGenerator::EffectContext::Plug(Handle<Object> lit) const { | 466 void FullCodeGenerator::EffectContext::Plug(Handle<Object> lit) const { |
| 467 } | 467 } |
| 468 | 468 |
| 469 | 469 |
| 470 void FullCodeGenerator::AccumulatorValueContext::Plug( | 470 void FullCodeGenerator::AccumulatorValueContext::Plug( |
| 471 Handle<Object> lit) const { | 471 Handle<Object> lit) const { |
| 472 if (lit->IsSmi()) { | 472 if (lit->IsSmi()) { |
| 473 __ SafeSet(result_register(), Immediate(lit)); | 473 __ SafeMove(result_register(), Immediate(lit)); |
| 474 } else { | 474 } else { |
| 475 __ Set(result_register(), Immediate(lit)); | 475 __ Move(result_register(), Immediate(lit)); |
| 476 } | 476 } |
| 477 } | 477 } |
| 478 | 478 |
| 479 | 479 |
| 480 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { | 480 void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const { |
| 481 if (lit->IsSmi()) { | 481 if (lit->IsSmi()) { |
| 482 __ SafePush(Immediate(lit)); | 482 __ SafePush(Immediate(lit)); |
| 483 } else { | 483 } else { |
| 484 __ push(Immediate(lit)); | 484 __ push(Immediate(lit)); |
| 485 } | 485 } |
| (...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1112 // No need for a write barrier, we are storing a Smi in the feedback vector. | 1112 // No need for a write barrier, we are storing a Smi in the feedback vector. |
| 1113 __ LoadHeapObject(ebx, FeedbackVector()); | 1113 __ LoadHeapObject(ebx, FeedbackVector()); |
| 1114 __ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(slot)), | 1114 __ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(slot)), |
| 1115 Immediate(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker))); | 1115 Immediate(Smi::FromInt(TypeFeedbackInfo::kForInSlowCaseMarker))); |
| 1116 | 1116 |
| 1117 __ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check | 1117 __ mov(ebx, Immediate(Smi::FromInt(1))); // Smi indicates slow check |
| 1118 __ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object | 1118 __ mov(ecx, Operand(esp, 0 * kPointerSize)); // Get enumerated object |
| 1119 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); | 1119 STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE); |
| 1120 __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx); | 1120 __ CmpObjectType(ecx, LAST_JS_PROXY_TYPE, ecx); |
| 1121 __ j(above, &non_proxy); | 1121 __ j(above, &non_proxy); |
| 1122 __ Set(ebx, Immediate(Smi::FromInt(0))); // Zero indicates proxy | 1122 __ Move(ebx, Immediate(Smi::FromInt(0))); // Zero indicates proxy |
| 1123 __ bind(&non_proxy); | 1123 __ bind(&non_proxy); |
| 1124 __ push(ebx); // Smi | 1124 __ push(ebx); // Smi |
| 1125 __ push(eax); // Array | 1125 __ push(eax); // Array |
| 1126 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); | 1126 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); |
| 1127 __ push(eax); // Fixed array length (as smi). | 1127 __ push(eax); // Fixed array length (as smi). |
| 1128 __ push(Immediate(Smi::FromInt(0))); // Initial index. | 1128 __ push(Immediate(Smi::FromInt(0))); // Initial index. |
| 1129 | 1129 |
| 1130 // Generate code for doing the condition check. | 1130 // Generate code for doing the condition check. |
| 1131 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 1131 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
| 1132 __ bind(&loop); | 1132 __ bind(&loop); |
| (...skipping 1692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2825 int arg_count = args->length(); | 2825 int arg_count = args->length(); |
| 2826 for (int i = 0; i < arg_count; i++) { | 2826 for (int i = 0; i < arg_count; i++) { |
| 2827 VisitForStackValue(args->at(i)); | 2827 VisitForStackValue(args->at(i)); |
| 2828 } | 2828 } |
| 2829 | 2829 |
| 2830 // Call the construct call builtin that handles allocation and | 2830 // Call the construct call builtin that handles allocation and |
| 2831 // constructor invocation. | 2831 // constructor invocation. |
| 2832 SetSourcePosition(expr->position()); | 2832 SetSourcePosition(expr->position()); |
| 2833 | 2833 |
| 2834 // Load function and argument count into edi and eax. | 2834 // Load function and argument count into edi and eax. |
| 2835 __ Set(eax, Immediate(arg_count)); | 2835 __ Move(eax, Immediate(arg_count)); |
| 2836 __ mov(edi, Operand(esp, arg_count * kPointerSize)); | 2836 __ mov(edi, Operand(esp, arg_count * kPointerSize)); |
| 2837 | 2837 |
| 2838 // Record call targets in unoptimized code. | 2838 // Record call targets in unoptimized code. |
| 2839 Handle<Object> uninitialized = | 2839 Handle<Object> uninitialized = |
| 2840 TypeFeedbackInfo::UninitializedSentinel(isolate()); | 2840 TypeFeedbackInfo::UninitializedSentinel(isolate()); |
| 2841 StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized); | 2841 StoreFeedbackVectorSlot(expr->CallNewFeedbackSlot(), uninitialized); |
| 2842 if (FLAG_pretenuring_call_new) { | 2842 if (FLAG_pretenuring_call_new) { |
| 2843 StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(), | 2843 StoreFeedbackVectorSlot(expr->AllocationSiteFeedbackSlot(), |
| 2844 isolate()->factory()->NewAllocationSite()); | 2844 isolate()->factory()->NewAllocationSite()); |
| 2845 ASSERT(expr->AllocationSiteFeedbackSlot() == | 2845 ASSERT(expr->AllocationSiteFeedbackSlot() == |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3216 | 3216 |
| 3217 | 3217 |
| 3218 void FullCodeGenerator::EmitArguments(CallRuntime* expr) { | 3218 void FullCodeGenerator::EmitArguments(CallRuntime* expr) { |
| 3219 ZoneList<Expression*>* args = expr->arguments(); | 3219 ZoneList<Expression*>* args = expr->arguments(); |
| 3220 ASSERT(args->length() == 1); | 3220 ASSERT(args->length() == 1); |
| 3221 | 3221 |
| 3222 // ArgumentsAccessStub expects the key in edx and the formal | 3222 // ArgumentsAccessStub expects the key in edx and the formal |
| 3223 // parameter count in eax. | 3223 // parameter count in eax. |
| 3224 VisitForAccumulatorValue(args->at(0)); | 3224 VisitForAccumulatorValue(args->at(0)); |
| 3225 __ mov(edx, eax); | 3225 __ mov(edx, eax); |
| 3226 __ Set(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters()))); | 3226 __ Move(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters()))); |
| 3227 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); | 3227 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); |
| 3228 __ CallStub(&stub); | 3228 __ CallStub(&stub); |
| 3229 context()->Plug(eax); | 3229 context()->Plug(eax); |
| 3230 } | 3230 } |
| 3231 | 3231 |
| 3232 | 3232 |
| 3233 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { | 3233 void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) { |
| 3234 ASSERT(expr->arguments()->length() == 0); | 3234 ASSERT(expr->arguments()->length() == 0); |
| 3235 | 3235 |
| 3236 Label exit; | 3236 Label exit; |
| 3237 // Get the number of formal parameters. | 3237 // Get the number of formal parameters. |
| 3238 __ Set(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters()))); | 3238 __ Move(eax, Immediate(Smi::FromInt(info_->scope()->num_parameters()))); |
| 3239 | 3239 |
| 3240 // Check if the calling frame is an arguments adaptor frame. | 3240 // Check if the calling frame is an arguments adaptor frame. |
| 3241 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 3241 __ mov(ebx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
| 3242 __ cmp(Operand(ebx, StandardFrameConstants::kContextOffset), | 3242 __ cmp(Operand(ebx, StandardFrameConstants::kContextOffset), |
| 3243 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 3243 Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
| 3244 __ j(not_equal, &exit); | 3244 __ j(not_equal, &exit); |
| 3245 | 3245 |
| 3246 // Arguments adaptor case: Read the arguments length from the | 3246 // Arguments adaptor case: Read the arguments length from the |
| 3247 // adaptor frame. | 3247 // adaptor frame. |
| 3248 __ mov(eax, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 3248 __ mov(eax, Operand(ebx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3595 &need_conversion, | 3595 &need_conversion, |
| 3596 &need_conversion, | 3596 &need_conversion, |
| 3597 &index_out_of_range, | 3597 &index_out_of_range, |
| 3598 STRING_INDEX_IS_NUMBER); | 3598 STRING_INDEX_IS_NUMBER); |
| 3599 generator.GenerateFast(masm_); | 3599 generator.GenerateFast(masm_); |
| 3600 __ jmp(&done); | 3600 __ jmp(&done); |
| 3601 | 3601 |
| 3602 __ bind(&index_out_of_range); | 3602 __ bind(&index_out_of_range); |
| 3603 // When the index is out of range, the spec requires us to return | 3603 // When the index is out of range, the spec requires us to return |
| 3604 // NaN. | 3604 // NaN. |
| 3605 __ Set(result, Immediate(isolate()->factory()->nan_value())); | 3605 __ Move(result, Immediate(isolate()->factory()->nan_value())); |
| 3606 __ jmp(&done); | 3606 __ jmp(&done); |
| 3607 | 3607 |
| 3608 __ bind(&need_conversion); | 3608 __ bind(&need_conversion); |
| 3609 // Move the undefined value into the result register, which will | 3609 // Move the undefined value into the result register, which will |
| 3610 // trigger conversion. | 3610 // trigger conversion. |
| 3611 __ Set(result, Immediate(isolate()->factory()->undefined_value())); | 3611 __ Move(result, Immediate(isolate()->factory()->undefined_value())); |
| 3612 __ jmp(&done); | 3612 __ jmp(&done); |
| 3613 | 3613 |
| 3614 NopRuntimeCallHelper call_helper; | 3614 NopRuntimeCallHelper call_helper; |
| 3615 generator.GenerateSlow(masm_, call_helper); | 3615 generator.GenerateSlow(masm_, call_helper); |
| 3616 | 3616 |
| 3617 __ bind(&done); | 3617 __ bind(&done); |
| 3618 context()->Plug(result); | 3618 context()->Plug(result); |
| 3619 } | 3619 } |
| 3620 | 3620 |
| 3621 | 3621 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3643 &need_conversion, | 3643 &need_conversion, |
| 3644 &need_conversion, | 3644 &need_conversion, |
| 3645 &index_out_of_range, | 3645 &index_out_of_range, |
| 3646 STRING_INDEX_IS_NUMBER); | 3646 STRING_INDEX_IS_NUMBER); |
| 3647 generator.GenerateFast(masm_); | 3647 generator.GenerateFast(masm_); |
| 3648 __ jmp(&done); | 3648 __ jmp(&done); |
| 3649 | 3649 |
| 3650 __ bind(&index_out_of_range); | 3650 __ bind(&index_out_of_range); |
| 3651 // When the index is out of range, the spec requires us to return | 3651 // When the index is out of range, the spec requires us to return |
| 3652 // the empty string. | 3652 // the empty string. |
| 3653 __ Set(result, Immediate(isolate()->factory()->empty_string())); | 3653 __ Move(result, Immediate(isolate()->factory()->empty_string())); |
| 3654 __ jmp(&done); | 3654 __ jmp(&done); |
| 3655 | 3655 |
| 3656 __ bind(&need_conversion); | 3656 __ bind(&need_conversion); |
| 3657 // Move smi zero into the result register, which will trigger | 3657 // Move smi zero into the result register, which will trigger |
| 3658 // conversion. | 3658 // conversion. |
| 3659 __ Set(result, Immediate(Smi::FromInt(0))); | 3659 __ Move(result, Immediate(Smi::FromInt(0))); |
| 3660 __ jmp(&done); | 3660 __ jmp(&done); |
| 3661 | 3661 |
| 3662 NopRuntimeCallHelper call_helper; | 3662 NopRuntimeCallHelper call_helper; |
| 3663 generator.GenerateSlow(masm_, call_helper); | 3663 generator.GenerateSlow(masm_, call_helper); |
| 3664 | 3664 |
| 3665 __ bind(&done); | 3665 __ bind(&done); |
| 3666 context()->Plug(result); | 3666 context()->Plug(result); |
| 3667 } | 3667 } |
| 3668 | 3668 |
| 3669 | 3669 |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3900 | 3900 |
| 3901 // Save the FixedArray containing array's elements. | 3901 // Save the FixedArray containing array's elements. |
| 3902 // End of array's live range. | 3902 // End of array's live range. |
| 3903 elements = array; | 3903 elements = array; |
| 3904 __ mov(elements, FieldOperand(array, JSArray::kElementsOffset)); | 3904 __ mov(elements, FieldOperand(array, JSArray::kElementsOffset)); |
| 3905 array = no_reg; | 3905 array = no_reg; |
| 3906 | 3906 |
| 3907 | 3907 |
| 3908 // Check that all array elements are sequential ASCII strings, and | 3908 // Check that all array elements are sequential ASCII strings, and |
| 3909 // accumulate the sum of their lengths, as a smi-encoded value. | 3909 // accumulate the sum of their lengths, as a smi-encoded value. |
| 3910 __ Set(index, Immediate(0)); | 3910 __ Move(index, Immediate(0)); |
| 3911 __ Set(string_length, Immediate(0)); | 3911 __ Move(string_length, Immediate(0)); |
| 3912 // Loop condition: while (index < length). | 3912 // Loop condition: while (index < length). |
| 3913 // Live loop registers: index, array_length, string, | 3913 // Live loop registers: index, array_length, string, |
| 3914 // scratch, string_length, elements. | 3914 // scratch, string_length, elements. |
| 3915 if (generate_debug_code_) { | 3915 if (generate_debug_code_) { |
| 3916 __ cmp(index, array_length); | 3916 __ cmp(index, array_length); |
| 3917 __ Assert(less, kNoEmptyArraysHereInEmitFastAsciiArrayJoin); | 3917 __ Assert(less, kNoEmptyArraysHereInEmitFastAsciiArrayJoin); |
| 3918 } | 3918 } |
| 3919 __ bind(&loop); | 3919 __ bind(&loop); |
| 3920 __ mov(string, FieldOperand(elements, | 3920 __ mov(string, FieldOperand(elements, |
| 3921 index, | 3921 index, |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4017 __ jmp(&done); | 4017 __ jmp(&done); |
| 4018 | 4018 |
| 4019 | 4019 |
| 4020 | 4020 |
| 4021 // One-character separator case | 4021 // One-character separator case |
| 4022 __ bind(&one_char_separator); | 4022 __ bind(&one_char_separator); |
| 4023 // Replace separator with its ASCII character value. | 4023 // Replace separator with its ASCII character value. |
| 4024 __ mov_b(scratch, FieldOperand(string, SeqOneByteString::kHeaderSize)); | 4024 __ mov_b(scratch, FieldOperand(string, SeqOneByteString::kHeaderSize)); |
| 4025 __ mov_b(separator_operand, scratch); | 4025 __ mov_b(separator_operand, scratch); |
| 4026 | 4026 |
| 4027 __ Set(index, Immediate(0)); | 4027 __ Move(index, Immediate(0)); |
| 4028 // Jump into the loop after the code that copies the separator, so the first | 4028 // Jump into the loop after the code that copies the separator, so the first |
| 4029 // element is not preceded by a separator | 4029 // element is not preceded by a separator |
| 4030 __ jmp(&loop_2_entry); | 4030 __ jmp(&loop_2_entry); |
| 4031 // Loop condition: while (index < length). | 4031 // Loop condition: while (index < length). |
| 4032 __ bind(&loop_2); | 4032 __ bind(&loop_2); |
| 4033 // Each iteration of the loop concatenates one string to the result. | 4033 // Each iteration of the loop concatenates one string to the result. |
| 4034 // Live values in registers: | 4034 // Live values in registers: |
| 4035 // index: which element of the elements array we are adding to the result. | 4035 // index: which element of the elements array we are adding to the result. |
| 4036 // result_pos: the position to which we are currently copying characters. | 4036 // result_pos: the position to which we are currently copying characters. |
| 4037 | 4037 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4054 __ add(index, Immediate(1)); | 4054 __ add(index, Immediate(1)); |
| 4055 | 4055 |
| 4056 __ cmp(index, array_length_operand); | 4056 __ cmp(index, array_length_operand); |
| 4057 __ j(less, &loop_2); // End while (index < length). | 4057 __ j(less, &loop_2); // End while (index < length). |
| 4058 __ jmp(&done); | 4058 __ jmp(&done); |
| 4059 | 4059 |
| 4060 | 4060 |
| 4061 // Long separator case (separator is more than one character). | 4061 // Long separator case (separator is more than one character). |
| 4062 __ bind(&long_separator); | 4062 __ bind(&long_separator); |
| 4063 | 4063 |
| 4064 __ Set(index, Immediate(0)); | 4064 __ Move(index, Immediate(0)); |
| 4065 // Jump into the loop after the code that copies the separator, so the first | 4065 // Jump into the loop after the code that copies the separator, so the first |
| 4066 // element is not preceded by a separator | 4066 // element is not preceded by a separator |
| 4067 __ jmp(&loop_3_entry); | 4067 __ jmp(&loop_3_entry); |
| 4068 // Loop condition: while (index < length). | 4068 // Loop condition: while (index < length). |
| 4069 __ bind(&loop_3); | 4069 __ bind(&loop_3); |
| 4070 // Each iteration of the loop concatenates one string to the result. | 4070 // Each iteration of the loop concatenates one string to the result. |
| 4071 // Live values in registers: | 4071 // Live values in registers: |
| 4072 // index: which element of the elements array we are adding to the result. | 4072 // index: which element of the elements array we are adding to the result. |
| 4073 // result_pos: the position to which we are currently copying characters. | 4073 // result_pos: the position to which we are currently copying characters. |
| 4074 | 4074 |
| (...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4903 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 4903 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 4904 Assembler::target_address_at(call_target_address, | 4904 Assembler::target_address_at(call_target_address, |
| 4905 unoptimized_code)); | 4905 unoptimized_code)); |
| 4906 return OSR_AFTER_STACK_CHECK; | 4906 return OSR_AFTER_STACK_CHECK; |
| 4907 } | 4907 } |
| 4908 | 4908 |
| 4909 | 4909 |
| 4910 } } // namespace v8::internal | 4910 } } // namespace v8::internal |
| 4911 | 4911 |
| 4912 #endif // V8_TARGET_ARCH_IA32 | 4912 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |