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 |