Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(342)

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 6713074: Require an isolate parameter for most external reference creation to (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Further cleanup Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/debug-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 RegisterAllocator register_allocator(this); 176 RegisterAllocator register_allocator(this);
177 allocator_ = &register_allocator; 177 allocator_ = &register_allocator;
178 ASSERT(frame_ == NULL); 178 ASSERT(frame_ == NULL);
179 frame_ = new VirtualFrame(); 179 frame_ = new VirtualFrame();
180 set_in_spilled_code(false); 180 set_in_spilled_code(false);
181 181
182 // Adjust for function-level loop nesting. 182 // Adjust for function-level loop nesting.
183 ASSERT_EQ(0, loop_nesting_); 183 ASSERT_EQ(0, loop_nesting_);
184 loop_nesting_ = info->is_in_loop() ? 1 : 0; 184 loop_nesting_ = info->is_in_loop() ? 1 : 0;
185 185
186 Isolate::Current()->set_jump_target_compiling_deferred_code(false); 186 masm()->isolate()->set_jump_target_compiling_deferred_code(false);
187 187
188 { 188 {
189 CodeGenState state(this); 189 CodeGenState state(this);
190 190
191 // Entry: 191 // Entry:
192 // Stack: receiver, arguments, return address. 192 // Stack: receiver, arguments, return address.
193 // ebp: caller's frame pointer 193 // ebp: caller's frame pointer
194 // esp: stack pointer 194 // esp: stack pointer
195 // edi: called JS function 195 // edi: called JS function
196 // esi: callee's context 196 // esi: callee's context
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 void CodeGenerator::ConvertInt32ResultToNumber(Result* value) { 549 void CodeGenerator::ConvertInt32ResultToNumber(Result* value) {
550 ASSERT(value->is_untagged_int32()); 550 ASSERT(value->is_untagged_int32());
551 if (value->is_register()) { 551 if (value->is_register()) {
552 Register val = value->reg(); 552 Register val = value->reg();
553 JumpTarget done; 553 JumpTarget done;
554 __ add(val, Operand(val)); 554 __ add(val, Operand(val));
555 done.Branch(no_overflow, value); 555 done.Branch(no_overflow, value);
556 __ sar(val, 1); 556 __ sar(val, 1);
557 // If there was an overflow, bits 30 and 31 of the original number disagree. 557 // If there was an overflow, bits 30 and 31 of the original number disagree.
558 __ xor_(val, 0x80000000u); 558 __ xor_(val, 0x80000000u);
559 if (Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 559 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
560 CpuFeatures::Scope fscope(SSE2); 560 CpuFeatures::Scope fscope(SSE2);
561 __ cvtsi2sd(xmm0, Operand(val)); 561 __ cvtsi2sd(xmm0, Operand(val));
562 } else { 562 } else {
563 // Move val to ST[0] in the FPU 563 // Move val to ST[0] in the FPU
564 // Push and pop are safe with respect to the virtual frame because 564 // Push and pop are safe with respect to the virtual frame because
565 // all synced elements are below the actual stack pointer. 565 // all synced elements are below the actual stack pointer.
566 __ push(val); 566 __ push(val);
567 __ fild_s(Operand(esp, 0)); 567 __ fild_s(Operand(esp, 0));
568 __ pop(val); 568 __ pop(val);
569 } 569 }
570 Result scratch = allocator_->Allocate(); 570 Result scratch = allocator_->Allocate();
571 ASSERT(scratch.is_register()); 571 ASSERT(scratch.is_register());
572 Label allocation_failed; 572 Label allocation_failed;
573 __ AllocateHeapNumber(val, scratch.reg(), 573 __ AllocateHeapNumber(val, scratch.reg(),
574 no_reg, &allocation_failed); 574 no_reg, &allocation_failed);
575 VirtualFrame* clone = new VirtualFrame(frame_); 575 VirtualFrame* clone = new VirtualFrame(frame_);
576 scratch.Unuse(); 576 scratch.Unuse();
577 if (Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 577 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
578 CpuFeatures::Scope fscope(SSE2); 578 CpuFeatures::Scope fscope(SSE2);
579 __ movdbl(FieldOperand(val, HeapNumber::kValueOffset), xmm0); 579 __ movdbl(FieldOperand(val, HeapNumber::kValueOffset), xmm0);
580 } else { 580 } else {
581 __ fstp_d(FieldOperand(val, HeapNumber::kValueOffset)); 581 __ fstp_d(FieldOperand(val, HeapNumber::kValueOffset));
582 } 582 }
583 done.Jump(value); 583 done.Jump(value);
584 584
585 // Establish the virtual frame, cloned from where AllocateHeapNumber 585 // Establish the virtual frame, cloned from where AllocateHeapNumber
586 // jumped to allocation_failed. 586 // jumped to allocation_failed.
587 RegisterFile empty_regs; 587 RegisterFile empty_regs;
588 SetFrame(clone, &empty_regs); 588 SetFrame(clone, &empty_regs);
589 __ bind(&allocation_failed); 589 __ bind(&allocation_failed);
590 if (!Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 590 if (!masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
591 // Pop the value from the floating point stack. 591 // Pop the value from the floating point stack.
592 __ fstp(0); 592 __ fstp(0);
593 } 593 }
594 unsafe_bailout_->Jump(); 594 unsafe_bailout_->Jump();
595 595
596 done.Bind(value); 596 done.Bind(value);
597 } else { 597 } else {
598 ASSERT(value->is_constant()); 598 ASSERT(value->is_constant());
599 } 599 }
600 value->set_untagged_int32(false); 600 value->set_untagged_int32(false);
601 value->set_type_info(TypeInfo::Integer32()); 601 value->set_type_info(TypeInfo::Integer32());
602 } 602 }
603 603
604 604
605 void CodeGenerator::Load(Expression* expr) { 605 void CodeGenerator::Load(Expression* expr) {
606 #ifdef DEBUG 606 #ifdef DEBUG
607 int original_height = frame_->height(); 607 int original_height = frame_->height();
608 #endif 608 #endif
609 ASSERT(!in_spilled_code()); 609 ASSERT(!in_spilled_code());
610 610
611 // If the expression should be a side-effect-free 32-bit int computation, 611 // If the expression should be a side-effect-free 32-bit int computation,
612 // compile that SafeInt32 path, and a bailout path. 612 // compile that SafeInt32 path, and a bailout path.
613 if (!in_safe_int32_mode() && 613 if (!in_safe_int32_mode() &&
614 safe_int32_mode_enabled() && 614 safe_int32_mode_enabled() &&
615 expr->side_effect_free() && 615 expr->side_effect_free() &&
616 expr->num_bit_ops() > 2 && 616 expr->num_bit_ops() > 2 &&
617 Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 617 masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
618 BreakTarget unsafe_bailout; 618 BreakTarget unsafe_bailout;
619 JumpTarget done; 619 JumpTarget done;
620 unsafe_bailout.set_expected_height(frame_->height()); 620 unsafe_bailout.set_expected_height(frame_->height());
621 LoadInSafeInt32Mode(expr, &unsafe_bailout); 621 LoadInSafeInt32Mode(expr, &unsafe_bailout);
622 done.Jump(); 622 done.Jump();
623 623
624 if (unsafe_bailout.is_linked()) { 624 if (unsafe_bailout.is_linked()) {
625 unsafe_bailout.Bind(); 625 unsafe_bailout.Bind();
626 LoadWithSafeInt32ModeDisabled(expr); 626 LoadWithSafeInt32ModeDisabled(expr);
627 } 627 }
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 OverwriteMode mode_; 988 OverwriteMode mode_;
989 Label answer_out_of_range_; 989 Label answer_out_of_range_;
990 Label non_smi_input_; 990 Label non_smi_input_;
991 Label constant_rhs_; 991 Label constant_rhs_;
992 Smi* smi_value_; 992 Smi* smi_value_;
993 }; 993 };
994 994
995 995
996 Label* DeferredInlineBinaryOperation::NonSmiInputLabel() { 996 Label* DeferredInlineBinaryOperation::NonSmiInputLabel() {
997 if (Token::IsBitOp(op_) && 997 if (Token::IsBitOp(op_) &&
998 Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 998 masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
999 return &non_smi_input_; 999 return &non_smi_input_;
1000 } else { 1000 } else {
1001 return entry_label(); 1001 return entry_label();
1002 } 1002 }
1003 } 1003 }
1004 1004
1005 1005
1006 void DeferredInlineBinaryOperation::JumpToAnswerOutOfRange(Condition cond) { 1006 void DeferredInlineBinaryOperation::JumpToAnswerOutOfRange(Condition cond) {
1007 __ j(cond, &answer_out_of_range_); 1007 __ j(cond, &answer_out_of_range_);
1008 } 1008 }
1009 1009
1010 1010
1011 void DeferredInlineBinaryOperation::JumpToConstantRhs(Condition cond, 1011 void DeferredInlineBinaryOperation::JumpToConstantRhs(Condition cond,
1012 Smi* smi_value) { 1012 Smi* smi_value) {
1013 smi_value_ = smi_value; 1013 smi_value_ = smi_value;
1014 __ j(cond, &constant_rhs_); 1014 __ j(cond, &constant_rhs_);
1015 } 1015 }
1016 1016
1017 1017
1018 void DeferredInlineBinaryOperation::Generate() { 1018 void DeferredInlineBinaryOperation::Generate() {
1019 // Registers are not saved implicitly for this stub, so we should not 1019 // Registers are not saved implicitly for this stub, so we should not
1020 // tread on the registers that were not passed to us. 1020 // tread on the registers that were not passed to us.
1021 if (Isolate::Current()->cpu_features()->IsSupported(SSE2) && 1021 if (masm()->isolate()->cpu_features()->IsSupported(SSE2) &&
1022 ((op_ == Token::ADD) || 1022 ((op_ == Token::ADD) ||
1023 (op_ == Token::SUB) || 1023 (op_ == Token::SUB) ||
1024 (op_ == Token::MUL) || 1024 (op_ == Token::MUL) ||
1025 (op_ == Token::DIV))) { 1025 (op_ == Token::DIV))) {
1026 CpuFeatures::Scope use_sse2(SSE2); 1026 CpuFeatures::Scope use_sse2(SSE2);
1027 Label call_runtime, after_alloc_failure; 1027 Label call_runtime, after_alloc_failure;
1028 Label left_smi, right_smi, load_right, do_op; 1028 Label left_smi, right_smi, load_right, do_op;
1029 if (!left_info_.IsSmi()) { 1029 if (!left_info_.IsSmi()) {
1030 __ test(left_, Immediate(kSmiTagMask)); 1030 __ test(left_, Immediate(kSmiTagMask));
1031 __ j(zero, &left_smi); 1031 __ j(zero, &left_smi);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 } 1147 }
1148 1148
1149 __ bind(&non_smi_input_); 1149 __ bind(&non_smi_input_);
1150 1150
1151 if (rhs_is_constant) { 1151 if (rhs_is_constant) {
1152 __ bind(&constant_rhs_); 1152 __ bind(&constant_rhs_);
1153 // In this case the input is a heap object and it is in the dst_ register. 1153 // In this case the input is a heap object and it is in the dst_ register.
1154 // The left_ and right_ registers have not been initialized yet. 1154 // The left_ and right_ registers have not been initialized yet.
1155 __ mov(right_, Immediate(smi_value_)); 1155 __ mov(right_, Immediate(smi_value_));
1156 __ mov(left_, Operand(dst_)); 1156 __ mov(left_, Operand(dst_));
1157 if (!Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 1157 if (!masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
1158 __ jmp(entry_label()); 1158 __ jmp(entry_label());
1159 return; 1159 return;
1160 } else { 1160 } else {
1161 CpuFeatures::Scope use_sse2(SSE2); 1161 CpuFeatures::Scope use_sse2(SSE2);
1162 __ JumpIfNotNumber(dst_, left_info_, entry_label()); 1162 __ JumpIfNotNumber(dst_, left_info_, entry_label());
1163 __ ConvertToInt32(dst_, left_, dst_, left_info_, entry_label()); 1163 __ ConvertToInt32(dst_, left_, dst_, left_info_, entry_label());
1164 __ SmiUntag(right_); 1164 __ SmiUntag(right_);
1165 } 1165 }
1166 } else { 1166 } else {
1167 // We know we have SSE2 here because otherwise the label is not linked (see 1167 // We know we have SSE2 here because otherwise the label is not linked (see
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 // Put a heap number pointer in left_. 1260 // Put a heap number pointer in left_.
1261 __ bind(&answer_out_of_range_); 1261 __ bind(&answer_out_of_range_);
1262 SaveRegisters(); 1262 SaveRegisters();
1263 if (mode_ == OVERWRITE_LEFT) { 1263 if (mode_ == OVERWRITE_LEFT) {
1264 __ test(left_, Immediate(kSmiTagMask)); 1264 __ test(left_, Immediate(kSmiTagMask));
1265 __ j(not_zero, &allocation_ok); 1265 __ j(not_zero, &allocation_ok);
1266 } 1266 }
1267 // This trashes right_. 1267 // This trashes right_.
1268 __ AllocateHeapNumber(left_, right_, no_reg, &after_alloc_failure2); 1268 __ AllocateHeapNumber(left_, right_, no_reg, &after_alloc_failure2);
1269 __ bind(&allocation_ok); 1269 __ bind(&allocation_ok);
1270 if (Isolate::Current()->cpu_features()->IsSupported(SSE2) && 1270 if (masm()->isolate()->cpu_features()->IsSupported(SSE2) &&
1271 op_ != Token::SHR) { 1271 op_ != Token::SHR) {
1272 CpuFeatures::Scope use_sse2(SSE2); 1272 CpuFeatures::Scope use_sse2(SSE2);
1273 ASSERT(Token::IsBitOp(op_)); 1273 ASSERT(Token::IsBitOp(op_));
1274 // Signed conversion. 1274 // Signed conversion.
1275 __ cvtsi2sd(xmm0, Operand(dst_)); 1275 __ cvtsi2sd(xmm0, Operand(dst_));
1276 __ movdbl(FieldOperand(left_, HeapNumber::kValueOffset), xmm0); 1276 __ movdbl(FieldOperand(left_, HeapNumber::kValueOffset), xmm0);
1277 } else { 1277 } else {
1278 if (op_ == Token::SHR) { 1278 if (op_ == Token::SHR) {
1279 __ push(Immediate(0)); // High word of unsigned value. 1279 __ push(Immediate(0)); // High word of unsigned value.
1280 __ push(dst_); 1280 __ push(dst_);
(...skipping 1744 matching lines...) Expand 10 before | Expand all | Expand 10 after
3025 } else { 3025 } else {
3026 // Do the smi check, then the comparison. 3026 // Do the smi check, then the comparison.
3027 __ test(left_reg, Immediate(kSmiTagMask)); 3027 __ test(left_reg, Immediate(kSmiTagMask));
3028 is_smi.Branch(zero, left_side, right_side); 3028 is_smi.Branch(zero, left_side, right_side);
3029 } 3029 }
3030 3030
3031 // Jump or fall through to here if we are comparing a non-smi to a 3031 // Jump or fall through to here if we are comparing a non-smi to a
3032 // constant smi. If the non-smi is a heap number and this is not 3032 // constant smi. If the non-smi is a heap number and this is not
3033 // a loop condition, inline the floating point code. 3033 // a loop condition, inline the floating point code.
3034 if (!is_loop_condition && 3034 if (!is_loop_condition &&
3035 Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 3035 masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
3036 // Right side is a constant smi and left side has been checked 3036 // Right side is a constant smi and left side has been checked
3037 // not to be a smi. 3037 // not to be a smi.
3038 CpuFeatures::Scope use_sse2(SSE2); 3038 CpuFeatures::Scope use_sse2(SSE2);
3039 JumpTarget not_number; 3039 JumpTarget not_number;
3040 __ cmp(FieldOperand(left_reg, HeapObject::kMapOffset), 3040 __ cmp(FieldOperand(left_reg, HeapObject::kMapOffset),
3041 Immediate(FACTORY->heap_number_map())); 3041 Immediate(FACTORY->heap_number_map()));
3042 not_number.Branch(not_equal, left_side); 3042 not_number.Branch(not_equal, left_side);
3043 __ movdbl(xmm1, 3043 __ movdbl(xmm1,
3044 FieldOperand(left_reg, HeapNumber::kValueOffset)); 3044 FieldOperand(left_reg, HeapNumber::kValueOffset));
3045 int value = Smi::cast(*right_val)->value(); 3045 int value = Smi::cast(*right_val)->value();
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
3189 3189
3190 3190
3191 void CodeGenerator::GenerateInlineNumberComparison(Result* left_side, 3191 void CodeGenerator::GenerateInlineNumberComparison(Result* left_side,
3192 Result* right_side, 3192 Result* right_side,
3193 Condition cc, 3193 Condition cc,
3194 ControlDestination* dest) { 3194 ControlDestination* dest) {
3195 ASSERT(left_side->is_register()); 3195 ASSERT(left_side->is_register());
3196 ASSERT(right_side->is_register()); 3196 ASSERT(right_side->is_register());
3197 3197
3198 JumpTarget not_numbers; 3198 JumpTarget not_numbers;
3199 if (Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 3199 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
3200 CpuFeatures::Scope use_sse2(SSE2); 3200 CpuFeatures::Scope use_sse2(SSE2);
3201 3201
3202 // Load left and right operand into registers xmm0 and xmm1 and compare. 3202 // Load left and right operand into registers xmm0 and xmm1 and compare.
3203 LoadComparisonOperandSSE2(masm_, left_side, xmm0, left_side, right_side, 3203 LoadComparisonOperandSSE2(masm_, left_side, xmm0, left_side, right_side,
3204 &not_numbers); 3204 &not_numbers);
3205 LoadComparisonOperandSSE2(masm_, right_side, xmm1, left_side, right_side, 3205 LoadComparisonOperandSSE2(masm_, right_side, xmm1, left_side, right_side,
3206 &not_numbers); 3206 &not_numbers);
3207 __ ucomisd(xmm0, xmm1); 3207 __ ucomisd(xmm0, xmm1);
3208 } else { 3208 } else {
3209 Label check_right, compare; 3209 Label check_right, compare;
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
3339 __ j(below, &build_args); 3339 __ j(below, &build_args);
3340 3340
3341 // Check that applicand.apply is Function.prototype.apply. 3341 // Check that applicand.apply is Function.prototype.apply.
3342 __ mov(eax, Operand(esp, kPointerSize)); 3342 __ mov(eax, Operand(esp, kPointerSize));
3343 __ test(eax, Immediate(kSmiTagMask)); 3343 __ test(eax, Immediate(kSmiTagMask));
3344 __ j(zero, &build_args); 3344 __ j(zero, &build_args);
3345 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ecx); 3345 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ecx);
3346 __ j(not_equal, &build_args); 3346 __ j(not_equal, &build_args);
3347 __ mov(ecx, FieldOperand(eax, JSFunction::kCodeEntryOffset)); 3347 __ mov(ecx, FieldOperand(eax, JSFunction::kCodeEntryOffset));
3348 __ sub(Operand(ecx), Immediate(Code::kHeaderSize - kHeapObjectTag)); 3348 __ sub(Operand(ecx), Immediate(Code::kHeaderSize - kHeapObjectTag));
3349 Handle<Code> apply_code(Isolate::Current()->builtins()->builtin( 3349 Handle<Code> apply_code(masm()->isolate()->builtins()->builtin(
3350 Builtins::FunctionApply)); 3350 Builtins::FunctionApply));
3351 __ cmp(Operand(ecx), Immediate(apply_code)); 3351 __ cmp(Operand(ecx), Immediate(apply_code));
3352 __ j(not_equal, &build_args); 3352 __ j(not_equal, &build_args);
3353 3353
3354 // Check that applicand is a function. 3354 // Check that applicand is a function.
3355 __ mov(edi, Operand(esp, 2 * kPointerSize)); 3355 __ mov(edi, Operand(esp, 2 * kPointerSize));
3356 __ test(edi, Immediate(kSmiTagMask)); 3356 __ test(edi, Immediate(kSmiTagMask));
3357 __ j(zero, &build_args); 3357 __ j(zero, &build_args);
3358 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); 3358 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
3359 __ j(not_equal, &build_args); 3359 __ j(not_equal, &build_args);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
3466 3466
3467 void DeferredStackCheck::Generate() { 3467 void DeferredStackCheck::Generate() {
3468 StackCheckStub stub; 3468 StackCheckStub stub;
3469 __ CallStub(&stub); 3469 __ CallStub(&stub);
3470 } 3470 }
3471 3471
3472 3472
3473 void CodeGenerator::CheckStack() { 3473 void CodeGenerator::CheckStack() {
3474 DeferredStackCheck* deferred = new DeferredStackCheck; 3474 DeferredStackCheck* deferred = new DeferredStackCheck;
3475 ExternalReference stack_limit = 3475 ExternalReference stack_limit =
3476 ExternalReference::address_of_stack_limit(); 3476 ExternalReference::address_of_stack_limit(masm()->isolate());
3477 __ cmp(esp, Operand::StaticVariable(stack_limit)); 3477 __ cmp(esp, Operand::StaticVariable(stack_limit));
3478 deferred->Branch(below); 3478 deferred->Branch(below);
3479 deferred->BindExit(); 3479 deferred->BindExit();
3480 } 3480 }
3481 3481
3482 3482
3483 void CodeGenerator::VisitAndSpill(Statement* statement) { 3483 void CodeGenerator::VisitAndSpill(Statement* statement) {
3484 ASSERT(in_spilled_code()); 3484 ASSERT(in_spilled_code());
3485 set_in_spilled_code(false); 3485 set_in_spilled_code(false);
3486 Visit(statement); 3486 Visit(statement);
(...skipping 1153 matching lines...) Expand 10 before | Expand all | Expand 10 after
4640 // After shadowing stops, the original targets are unshadowed and the 4640 // After shadowing stops, the original targets are unshadowed and the
4641 // ShadowTargets represent the formerly shadowing targets. 4641 // ShadowTargets represent the formerly shadowing targets.
4642 bool has_unlinks = false; 4642 bool has_unlinks = false;
4643 for (int i = 0; i < shadows.length(); i++) { 4643 for (int i = 0; i < shadows.length(); i++) {
4644 shadows[i]->StopShadowing(); 4644 shadows[i]->StopShadowing();
4645 has_unlinks = has_unlinks || shadows[i]->is_linked(); 4645 has_unlinks = has_unlinks || shadows[i]->is_linked();
4646 } 4646 }
4647 function_return_is_shadowed_ = function_return_was_shadowed; 4647 function_return_is_shadowed_ = function_return_was_shadowed;
4648 4648
4649 // Get an external reference to the handler address. 4649 // Get an external reference to the handler address.
4650 ExternalReference handler_address(Isolate::k_handler_address); 4650 ExternalReference handler_address(Isolate::k_handler_address,
4651 masm()->isolate());
4651 4652
4652 // Make sure that there's nothing left on the stack above the 4653 // Make sure that there's nothing left on the stack above the
4653 // handler structure. 4654 // handler structure.
4654 if (FLAG_debug_code) { 4655 if (FLAG_debug_code) {
4655 __ mov(eax, Operand::StaticVariable(handler_address)); 4656 __ mov(eax, Operand::StaticVariable(handler_address));
4656 __ cmp(esp, Operand(eax)); 4657 __ cmp(esp, Operand(eax));
4657 __ Assert(equal, "stack pointer should point to top handler"); 4658 __ Assert(equal, "stack pointer should point to top handler");
4658 } 4659 }
4659 4660
4660 // If we can fall off the end of the try block, unlink from try chain. 4661 // If we can fall off the end of the try block, unlink from try chain.
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
4766 // After shadowing stops, the original targets are unshadowed and the 4767 // After shadowing stops, the original targets are unshadowed and the
4767 // ShadowTargets represent the formerly shadowing targets. 4768 // ShadowTargets represent the formerly shadowing targets.
4768 int nof_unlinks = 0; 4769 int nof_unlinks = 0;
4769 for (int i = 0; i < shadows.length(); i++) { 4770 for (int i = 0; i < shadows.length(); i++) {
4770 shadows[i]->StopShadowing(); 4771 shadows[i]->StopShadowing();
4771 if (shadows[i]->is_linked()) nof_unlinks++; 4772 if (shadows[i]->is_linked()) nof_unlinks++;
4772 } 4773 }
4773 function_return_is_shadowed_ = function_return_was_shadowed; 4774 function_return_is_shadowed_ = function_return_was_shadowed;
4774 4775
4775 // Get an external reference to the handler address. 4776 // Get an external reference to the handler address.
4776 ExternalReference handler_address(Isolate::k_handler_address); 4777 ExternalReference handler_address(Isolate::k_handler_address,
4778 masm()->isolate());
4777 4779
4778 // If we can fall off the end of the try block, unlink from the try 4780 // If we can fall off the end of the try block, unlink from the try
4779 // chain and set the state on the frame to FALLING. 4781 // chain and set the state on the frame to FALLING.
4780 if (has_valid_frame()) { 4782 if (has_valid_frame()) {
4781 // The next handler address is on top of the frame. 4783 // The next handler address is on top of the frame.
4782 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); 4784 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
4783 frame_->EmitPop(Operand::StaticVariable(handler_address)); 4785 frame_->EmitPop(Operand::StaticVariable(handler_address));
4784 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1); 4786 frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
4785 4787
4786 // Fake a top of stack value (unneeded when FALLING) and set the 4788 // Fake a top of stack value (unneeded when FALLING) and set the
(...skipping 2652 matching lines...) Expand 10 before | Expand all | Expand 10 after
7439 __ jmp(&heapnumber_allocated); 7441 __ jmp(&heapnumber_allocated);
7440 7442
7441 __ bind(&slow_allocate_heapnumber); 7443 __ bind(&slow_allocate_heapnumber);
7442 // Allocate a heap number. 7444 // Allocate a heap number.
7443 __ CallRuntime(Runtime::kNumberAlloc, 0); 7445 __ CallRuntime(Runtime::kNumberAlloc, 0);
7444 __ mov(edi, eax); 7446 __ mov(edi, eax);
7445 7447
7446 __ bind(&heapnumber_allocated); 7448 __ bind(&heapnumber_allocated);
7447 7449
7448 __ PrepareCallCFunction(0, ebx); 7450 __ PrepareCallCFunction(0, ebx);
7449 __ CallCFunction(ExternalReference::random_uint32_function(), 0); 7451 __ CallCFunction(ExternalReference::random_uint32_function(masm()->isolate()),
7452 0);
7450 7453
7451 // Convert 32 random bits in eax to 0.(32 random bits) in a double 7454 // Convert 32 random bits in eax to 0.(32 random bits) in a double
7452 // by computing: 7455 // by computing:
7453 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). 7456 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)).
7454 // This is implemented on both SSE2 and FPU. 7457 // This is implemented on both SSE2 and FPU.
7455 if (Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 7458 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
7456 CpuFeatures::Scope fscope(SSE2); 7459 CpuFeatures::Scope fscope(SSE2);
7457 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single. 7460 __ mov(ebx, Immediate(0x49800000)); // 1.0 x 2^20 as single.
7458 __ movd(xmm1, Operand(ebx)); 7461 __ movd(xmm1, Operand(ebx));
7459 __ movd(xmm0, Operand(eax)); 7462 __ movd(xmm0, Operand(eax));
7460 __ cvtss2sd(xmm1, xmm1); 7463 __ cvtss2sd(xmm1, xmm1);
7461 __ pxor(xmm0, xmm1); 7464 __ pxor(xmm0, xmm1);
7462 __ subsd(xmm0, xmm1); 7465 __ subsd(xmm0, xmm1);
7463 __ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0); 7466 __ movdbl(FieldOperand(edi, HeapNumber::kValueOffset), xmm0);
7464 } else { 7467 } else {
7465 // 0x4130000000000000 is 1.0 x 2^20 as a double. 7468 // 0x4130000000000000 is 1.0 x 2^20 as a double.
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
7662 } 7665 }
7663 7666
7664 7667
7665 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { 7668 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) {
7666 ASSERT_EQ(2, args->length()); 7669 ASSERT_EQ(2, args->length());
7667 7670
7668 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 7671 ASSERT_NE(NULL, args->at(0)->AsLiteral());
7669 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); 7672 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
7670 7673
7671 Handle<FixedArray> jsfunction_result_caches( 7674 Handle<FixedArray> jsfunction_result_caches(
7672 Isolate::Current()->global_context()->jsfunction_result_caches()); 7675 masm()->isolate()->global_context()->jsfunction_result_caches());
7673 if (jsfunction_result_caches->length() <= cache_id) { 7676 if (jsfunction_result_caches->length() <= cache_id) {
7674 __ Abort("Attempt to use undefined cache."); 7677 __ Abort("Attempt to use undefined cache.");
7675 frame_->Push(FACTORY->undefined_value()); 7678 frame_->Push(FACTORY->undefined_value());
7676 return; 7679 return;
7677 } 7680 }
7678 7681
7679 Load(args->at(1)); 7682 Load(args->at(1));
7680 Result key = frame_->Pop(); 7683 Result key = frame_->Pop();
7681 key.ToRegister(); 7684 key.ToRegister();
7682 7685
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
7851 7854
7852 7855
7853 // Generates the Math.pow method. Only handles special cases and 7856 // Generates the Math.pow method. Only handles special cases and
7854 // branches to the runtime system for everything else. Please note 7857 // branches to the runtime system for everything else. Please note
7855 // that this function assumes that the callsite has executed ToNumber 7858 // that this function assumes that the callsite has executed ToNumber
7856 // on both arguments. 7859 // on both arguments.
7857 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) { 7860 void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) {
7858 ASSERT(args->length() == 2); 7861 ASSERT(args->length() == 2);
7859 Load(args->at(0)); 7862 Load(args->at(0));
7860 Load(args->at(1)); 7863 Load(args->at(1));
7861 if (!Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 7864 if (!masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
7862 Result res = frame_->CallRuntime(Runtime::kMath_pow, 2); 7865 Result res = frame_->CallRuntime(Runtime::kMath_pow, 2);
7863 frame_->Push(&res); 7866 frame_->Push(&res);
7864 } else { 7867 } else {
7865 CpuFeatures::Scope use_sse2(SSE2); 7868 CpuFeatures::Scope use_sse2(SSE2);
7866 Label allocate_return; 7869 Label allocate_return;
7867 // Load the two operands while leaving the values on the frame. 7870 // Load the two operands while leaving the values on the frame.
7868 frame()->Dup(); 7871 frame()->Dup();
7869 Result exponent = frame()->Pop(); 7872 Result exponent = frame()->Pop();
7870 exponent.ToRegister(); 7873 exponent.ToRegister();
7871 frame()->Spill(exponent.reg()); 7874 frame()->Spill(exponent.reg());
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
8068 frame_->Push(&result); 8071 frame_->Push(&result);
8069 } 8072 }
8070 8073
8071 8074
8072 // Generates the Math.sqrt method. Please note - this function assumes that 8075 // Generates the Math.sqrt method. Please note - this function assumes that
8073 // the callsite has executed ToNumber on the argument. 8076 // the callsite has executed ToNumber on the argument.
8074 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) { 8077 void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) {
8075 ASSERT_EQ(args->length(), 1); 8078 ASSERT_EQ(args->length(), 1);
8076 Load(args->at(0)); 8079 Load(args->at(0));
8077 8080
8078 if (!Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 8081 if (!masm()->isolate()->cpu_features()->IsSupported(SSE2)) {
8079 Result result = frame()->CallRuntime(Runtime::kMath_sqrt, 1); 8082 Result result = frame()->CallRuntime(Runtime::kMath_sqrt, 1);
8080 frame()->Push(&result); 8083 frame()->Push(&result);
8081 } else { 8084 } else {
8082 CpuFeatures::Scope use_sse2(SSE2); 8085 CpuFeatures::Scope use_sse2(SSE2);
8083 // Leave original value on the frame if we need to call runtime. 8086 // Leave original value on the frame if we need to call runtime.
8084 frame()->Dup(); 8087 frame()->Dup();
8085 Result result = frame()->Pop(); 8088 Result result = frame()->Pop();
8086 result.ToRegister(); 8089 result.ToRegister();
8087 frame()->Spill(result.reg()); 8090 frame()->Spill(result.reg());
8088 Label runtime; 8091 Label runtime;
(...skipping 1292 matching lines...) Expand 10 before | Expand all | Expand 10 after
9381 bool is_contextual_; 9384 bool is_contextual_;
9382 bool is_dont_delete_; 9385 bool is_dont_delete_;
9383 }; 9386 };
9384 9387
9385 9388
9386 void DeferredReferenceGetNamedValue::Generate() { 9389 void DeferredReferenceGetNamedValue::Generate() {
9387 if (!receiver_.is(eax)) { 9390 if (!receiver_.is(eax)) {
9388 __ mov(eax, receiver_); 9391 __ mov(eax, receiver_);
9389 } 9392 }
9390 __ Set(ecx, Immediate(name_)); 9393 __ Set(ecx, Immediate(name_));
9391 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 9394 Handle<Code> ic(masm()->isolate()->builtins()->builtin(
9392 Builtins::LoadIC_Initialize)); 9395 Builtins::LoadIC_Initialize));
9393 RelocInfo::Mode mode = is_contextual_ 9396 RelocInfo::Mode mode = is_contextual_
9394 ? RelocInfo::CODE_TARGET_CONTEXT 9397 ? RelocInfo::CODE_TARGET_CONTEXT
9395 : RelocInfo::CODE_TARGET; 9398 : RelocInfo::CODE_TARGET;
9396 __ call(ic, mode); 9399 __ call(ic, mode);
9397 // The call must be followed by: 9400 // The call must be followed by:
9398 // - a test eax instruction to indicate that the inobject property 9401 // - a test eax instruction to indicate that the inobject property
9399 // case was inlined. 9402 // case was inlined.
9400 // - a mov ecx or mov edx instruction to indicate that the 9403 // - a mov ecx or mov edx instruction to indicate that the
9401 // contextual property load was inlined. 9404 // contextual property load was inlined.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
9461 } 9464 }
9462 } else { 9465 } else {
9463 __ xchg(edx, eax); 9466 __ xchg(edx, eax);
9464 } 9467 }
9465 // Calculate the delta from the IC call instruction to the map check 9468 // Calculate the delta from the IC call instruction to the map check
9466 // cmp instruction in the inlined version. This delta is stored in 9469 // cmp instruction in the inlined version. This delta is stored in
9467 // a test(eax, delta) instruction after the call so that we can find 9470 // a test(eax, delta) instruction after the call so that we can find
9468 // it in the IC initialization code and patch the cmp instruction. 9471 // it in the IC initialization code and patch the cmp instruction.
9469 // This means that we cannot allow test instructions after calls to 9472 // This means that we cannot allow test instructions after calls to
9470 // KeyedLoadIC stubs in other places. 9473 // KeyedLoadIC stubs in other places.
9471 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 9474 Handle<Code> ic(masm()->isolate()->builtins()->builtin(
9472 Builtins::KeyedLoadIC_Initialize)); 9475 Builtins::KeyedLoadIC_Initialize));
9473 __ call(ic, RelocInfo::CODE_TARGET); 9476 __ call(ic, RelocInfo::CODE_TARGET);
9474 // The delta from the start of the map-compare instruction to the 9477 // The delta from the start of the map-compare instruction to the
9475 // test instruction. We use masm_-> directly here instead of the __ 9478 // test instruction. We use masm_-> directly here instead of the __
9476 // macro because the macro sometimes uses macro expansion to turn 9479 // macro because the macro sometimes uses macro expansion to turn
9477 // into something that can't return a value. This is encountered 9480 // into something that can't return a value. This is encountered
9478 // when doing generated code coverage tests. 9481 // when doing generated code coverage tests.
9479 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); 9482 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site());
9480 // Here we use masm_-> instead of the __ macro because this is the 9483 // Here we use masm_-> instead of the __ macro because this is the
9481 // instruction that gets patched and coverage code gets in the way. 9484 // instruction that gets patched and coverage code gets in the way.
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
9563 } 9566 }
9564 } 9567 }
9565 } else { // Key is not in edx or ecx. 9568 } else { // Key is not in edx or ecx.
9566 if (!receiver_.is(edx)) { 9569 if (!receiver_.is(edx)) {
9567 __ mov(edx, receiver_); 9570 __ mov(edx, receiver_);
9568 } 9571 }
9569 __ mov(ecx, key_); 9572 __ mov(ecx, key_);
9570 } 9573 }
9571 9574
9572 // Call the IC stub. 9575 // Call the IC stub.
9573 Handle<Code> ic(Isolate::Current()->builtins()->builtin( 9576 Handle<Code> ic(masm()->isolate()->builtins()->builtin(
9574 (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict 9577 (strict_mode_ == kStrictMode) ? Builtins::KeyedStoreIC_Initialize_Strict
9575 : Builtins::KeyedStoreIC_Initialize)); 9578 : Builtins::KeyedStoreIC_Initialize));
9576 __ call(ic, RelocInfo::CODE_TARGET); 9579 __ call(ic, RelocInfo::CODE_TARGET);
9577 // The delta from the start of the map-compare instruction to the 9580 // The delta from the start of the map-compare instruction to the
9578 // test instruction. We use masm_-> directly here instead of the 9581 // test instruction. We use masm_-> directly here instead of the
9579 // __ macro because the macro sometimes uses macro expansion to turn 9582 // __ macro because the macro sometimes uses macro expansion to turn
9580 // into something that can't return a value. This is encountered 9583 // into something that can't return a value. This is encountered
9581 // when doing generated code coverage tests. 9584 // when doing generated code coverage tests.
9582 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); 9585 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site());
9583 // Here we use masm_-> instead of the __ macro because this is the 9586 // Here we use masm_-> instead of the __ macro because this is the
9584 // instruction that gets patched and coverage code gets in the way. 9587 // instruction that gets patched and coverage code gets in the way.
9585 masm_->test(eax, Immediate(-delta_to_patch_site)); 9588 masm_->test(eax, Immediate(-delta_to_patch_site));
9586 // Restore value (returned from store IC) register. 9589 // Restore value (returned from store IC) register.
9587 if (!old_value.is(eax)) __ mov(old_value, eax); 9590 if (!old_value.is(eax)) __ mov(old_value, eax);
9588 } 9591 }
9589 9592
9590 9593
9591 Result CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) { 9594 Result CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
9592 #ifdef DEBUG 9595 #ifdef DEBUG
9593 int original_height = frame()->height(); 9596 int original_height = frame()->height();
9594 #endif 9597 #endif
9595 9598
9596 bool contextual_load_in_builtin = 9599 bool contextual_load_in_builtin =
9597 is_contextual && 9600 is_contextual &&
9598 (Isolate::Current()->bootstrapper()->IsActive() || 9601 (masm()->isolate()->bootstrapper()->IsActive() ||
9599 (!info_->closure().is_null() && info_->closure()->IsBuiltin())); 9602 (!info_->closure().is_null() && info_->closure()->IsBuiltin()));
9600 9603
9601 Result result; 9604 Result result;
9602 // Do not inline in the global code or when not in loop. 9605 // Do not inline in the global code or when not in loop.
9603 if (scope()->is_global_scope() || 9606 if (scope()->is_global_scope() ||
9604 loop_nesting() == 0 || 9607 loop_nesting() == 0 ||
9605 contextual_load_in_builtin) { 9608 contextual_load_in_builtin) {
9606 Comment cmnt(masm(), "[ Load from named Property"); 9609 Comment cmnt(masm(), "[ Load from named Property");
9607 frame()->Push(name); 9610 frame()->Push(name);
9608 9611
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after
10186 int stack_offset = 0; // Update if we change the stack height. 10189 int stack_offset = 0; // Update if we change the stack height.
10187 10190
10188 if (FLAG_debug_code) { 10191 if (FLAG_debug_code) {
10189 __ cmp(Operand(esp, kSizeOffset + stack_offset), 10192 __ cmp(Operand(esp, kSizeOffset + stack_offset),
10190 Immediate(kMinComplexMemCopy)); 10193 Immediate(kMinComplexMemCopy));
10191 Label ok; 10194 Label ok;
10192 __ j(greater_equal, &ok); 10195 __ j(greater_equal, &ok);
10193 __ int3(); 10196 __ int3();
10194 __ bind(&ok); 10197 __ bind(&ok);
10195 } 10198 }
10196 if (Isolate::Current()->cpu_features()->IsSupported(SSE2)) { 10199 if (masm.isolate()->cpu_features()->IsSupported(SSE2)) {
10197 CpuFeatures::Scope enable(SSE2); 10200 CpuFeatures::Scope enable(SSE2);
10198 __ push(edi); 10201 __ push(edi);
10199 __ push(esi); 10202 __ push(esi);
10200 stack_offset += 2 * kPointerSize; 10203 stack_offset += 2 * kPointerSize;
10201 Register dst = edi; 10204 Register dst = edi;
10202 Register src = esi; 10205 Register src = esi;
10203 Register count = ecx; 10206 Register count = ecx;
10204 __ mov(dst, Operand(esp, stack_offset + kDestinationOffset)); 10207 __ mov(dst, Operand(esp, stack_offset + kDestinationOffset));
10205 __ mov(src, Operand(esp, stack_offset + kSourceOffset)); 10208 __ mov(src, Operand(esp, stack_offset + kSourceOffset));
10206 __ mov(count, Operand(esp, stack_offset + kSizeOffset)); 10209 __ mov(count, Operand(esp, stack_offset + kSizeOffset));
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
10367 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size); 10370 memcpy(chunk->GetStartAddress(), desc.buffer, desc.instr_size);
10368 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size); 10371 CPU::FlushICache(chunk->GetStartAddress(), desc.instr_size);
10369 return FUNCTION_CAST<MemCopyFunction>(chunk->GetStartAddress()); 10372 return FUNCTION_CAST<MemCopyFunction>(chunk->GetStartAddress());
10370 } 10373 }
10371 10374
10372 #undef __ 10375 #undef __
10373 10376
10374 } } // namespace v8::internal 10377 } } // namespace v8::internal
10375 10378
10376 #endif // V8_TARGET_ARCH_IA32 10379 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/debug-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698