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

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

Issue 3119005: ARM: Remove some spill scopes (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 4 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 | « no previous file | no next file » | 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 4546 matching lines...) Expand 10 before | Expand all | Expand 10 after
4557 Label need_conversion_; 4557 Label need_conversion_;
4558 Label index_out_of_range_; 4558 Label index_out_of_range_;
4559 4559
4560 StringCharCodeAtGenerator char_code_at_generator_; 4560 StringCharCodeAtGenerator char_code_at_generator_;
4561 }; 4561 };
4562 4562
4563 4563
4564 // This generates code that performs a String.prototype.charCodeAt() call 4564 // This generates code that performs a String.prototype.charCodeAt() call
4565 // or returns a smi in order to trigger conversion. 4565 // or returns a smi in order to trigger conversion.
4566 void CodeGenerator::GenerateStringCharCodeAt(ZoneList<Expression*>* args) { 4566 void CodeGenerator::GenerateStringCharCodeAt(ZoneList<Expression*>* args) {
4567 VirtualFrame::SpilledScope spilled_scope(frame_);
4568 Comment(masm_, "[ GenerateStringCharCodeAt"); 4567 Comment(masm_, "[ GenerateStringCharCodeAt");
4569 ASSERT(args->length() == 2); 4568 ASSERT(args->length() == 2);
4570 4569
4571 Load(args->at(0)); 4570 Load(args->at(0));
4572 Load(args->at(1)); 4571 Load(args->at(1));
4573 4572
4574 Register index = r1; 4573 Register index = frame_->PopToRegister();
4575 Register object = r2; 4574 Register object = frame_->PopToRegister(index);
4576
4577 frame_->EmitPop(r1);
4578 frame_->EmitPop(r2);
4579 4575
4580 // We need two extra registers. 4576 // We need two extra registers.
4581 Register scratch = r3; 4577 Register scratch = VirtualFrame::scratch0();
4582 Register result = r0; 4578 Register result = VirtualFrame::scratch1();
4583 4579
4584 DeferredStringCharCodeAt* deferred = 4580 DeferredStringCharCodeAt* deferred =
4585 new DeferredStringCharCodeAt(object, 4581 new DeferredStringCharCodeAt(object,
4586 index, 4582 index,
4587 scratch, 4583 scratch,
4588 result); 4584 result);
4589 deferred->fast_case_generator()->GenerateFast(masm_); 4585 deferred->fast_case_generator()->GenerateFast(masm_);
4590 deferred->BindExit(); 4586 deferred->BindExit();
4591 frame_->EmitPush(result); 4587 frame_->EmitPush(result);
4592 } 4588 }
(...skipping 14 matching lines...) Expand all
4607 char_from_code_generator_.GenerateSlow(masm(), call_helper); 4603 char_from_code_generator_.GenerateSlow(masm(), call_helper);
4608 } 4604 }
4609 4605
4610 private: 4606 private:
4611 StringCharFromCodeGenerator char_from_code_generator_; 4607 StringCharFromCodeGenerator char_from_code_generator_;
4612 }; 4608 };
4613 4609
4614 4610
4615 // Generates code for creating a one-char string from a char code. 4611 // Generates code for creating a one-char string from a char code.
4616 void CodeGenerator::GenerateStringCharFromCode(ZoneList<Expression*>* args) { 4612 void CodeGenerator::GenerateStringCharFromCode(ZoneList<Expression*>* args) {
4617 VirtualFrame::SpilledScope spilled_scope(frame_);
4618 Comment(masm_, "[ GenerateStringCharFromCode"); 4613 Comment(masm_, "[ GenerateStringCharFromCode");
4619 ASSERT(args->length() == 1); 4614 ASSERT(args->length() == 1);
4620 4615
4621 Load(args->at(0)); 4616 Load(args->at(0));
4622 4617
4623 Register code = r1; 4618 Register result = frame_->GetTOSRegister();
4624 Register result = r0; 4619 Register code = frame_->PopToRegister(result);
4625
4626 frame_->EmitPop(code);
4627 4620
4628 DeferredStringCharFromCode* deferred = new DeferredStringCharFromCode( 4621 DeferredStringCharFromCode* deferred = new DeferredStringCharFromCode(
4629 code, result); 4622 code, result);
4630 deferred->fast_case_generator()->GenerateFast(masm_); 4623 deferred->fast_case_generator()->GenerateFast(masm_);
4631 deferred->BindExit(); 4624 deferred->BindExit();
4632 frame_->EmitPush(result); 4625 frame_->EmitPush(result);
4633 } 4626 }
4634 4627
4635 4628
4636 class DeferredStringCharAt : public DeferredCode { 4629 class DeferredStringCharAt : public DeferredCode {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4678 Label need_conversion_; 4671 Label need_conversion_;
4679 Label index_out_of_range_; 4672 Label index_out_of_range_;
4680 4673
4681 StringCharAtGenerator char_at_generator_; 4674 StringCharAtGenerator char_at_generator_;
4682 }; 4675 };
4683 4676
4684 4677
4685 // This generates code that performs a String.prototype.charAt() call 4678 // This generates code that performs a String.prototype.charAt() call
4686 // or returns a smi in order to trigger conversion. 4679 // or returns a smi in order to trigger conversion.
4687 void CodeGenerator::GenerateStringCharAt(ZoneList<Expression*>* args) { 4680 void CodeGenerator::GenerateStringCharAt(ZoneList<Expression*>* args) {
4688 VirtualFrame::SpilledScope spilled_scope(frame_);
4689 Comment(masm_, "[ GenerateStringCharAt"); 4681 Comment(masm_, "[ GenerateStringCharAt");
4690 ASSERT(args->length() == 2); 4682 ASSERT(args->length() == 2);
4691 4683
4692 Load(args->at(0)); 4684 Load(args->at(0));
4693 Load(args->at(1)); 4685 Load(args->at(1));
4694 4686
4695 Register index = r1; 4687 Register index = frame_->PopToRegister();
4696 Register object = r2; 4688 Register object = frame_->PopToRegister(index);
4697
4698 frame_->EmitPop(r1);
4699 frame_->EmitPop(r2);
4700 4689
4701 // We need three extra registers. 4690 // We need three extra registers.
4702 Register scratch1 = r3; 4691 Register scratch1 = VirtualFrame::scratch0();
4703 Register scratch2 = r4; 4692 Register scratch2 = VirtualFrame::scratch1();
4704 Register result = r0; 4693 // Use r6 without notifying the virtual frame.
4694 Register result = r6;
4705 4695
4706 DeferredStringCharAt* deferred = 4696 DeferredStringCharAt* deferred =
4707 new DeferredStringCharAt(object, 4697 new DeferredStringCharAt(object,
4708 index, 4698 index,
4709 scratch1, 4699 scratch1,
4710 scratch2, 4700 scratch2,
4711 result); 4701 result);
4712 deferred->fast_case_generator()->GenerateFast(masm_); 4702 deferred->fast_case_generator()->GenerateFast(masm_);
4713 deferred->BindExit(); 4703 deferred->BindExit();
4714 frame_->EmitPush(result); 4704 frame_->EmitPush(result);
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
4873 // adaptor frame. 4863 // adaptor frame.
4874 __ ldr(tos, 4864 __ ldr(tos,
4875 MemOperand(scratch0, ArgumentsAdaptorFrameConstants::kLengthOffset), 4865 MemOperand(scratch0, ArgumentsAdaptorFrameConstants::kLengthOffset),
4876 eq); 4866 eq);
4877 4867
4878 frame_->EmitPush(tos); 4868 frame_->EmitPush(tos);
4879 } 4869 }
4880 4870
4881 4871
4882 void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) { 4872 void CodeGenerator::GenerateArguments(ZoneList<Expression*>* args) {
4883 VirtualFrame::SpilledScope spilled_scope(frame_);
4884 ASSERT(args->length() == 1); 4873 ASSERT(args->length() == 1);
4885 4874
4886 // Satisfy contract with ArgumentsAccessStub: 4875 // Satisfy contract with ArgumentsAccessStub:
4887 // Load the key into r1 and the formal parameters count into r0. 4876 // Load the key into r1 and the formal parameters count into r0.
4888 Load(args->at(0)); 4877 Load(args->at(0));
4889 frame_->EmitPop(r1); 4878 frame_->PopToR1();
4879 frame_->SpillAll();
4890 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters()))); 4880 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters())));
4891 4881
4892 // Call the shared stub to get to arguments[key]. 4882 // Call the shared stub to get to arguments[key].
4893 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT); 4883 ArgumentsAccessStub stub(ArgumentsAccessStub::READ_ELEMENT);
4894 frame_->CallStub(&stub, 0); 4884 frame_->CallStub(&stub, 0);
4895 frame_->EmitPush(r0); 4885 frame_->EmitPush(r0);
4896 } 4886 }
4897 4887
4898 4888
4899 void CodeGenerator::GenerateRandomHeapNumber( 4889 void CodeGenerator::GenerateRandomHeapNumber(
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
5107 virtual void Generate(); 5097 virtual void Generate();
5108 5098
5109 private: 5099 private:
5110 Register dst_, cache_, key_; 5100 Register dst_, cache_, key_;
5111 }; 5101 };
5112 5102
5113 5103
5114 void DeferredSearchCache::Generate() { 5104 void DeferredSearchCache::Generate() {
5115 __ Push(cache_, key_); 5105 __ Push(cache_, key_);
5116 __ CallRuntime(Runtime::kGetFromCache, 2); 5106 __ CallRuntime(Runtime::kGetFromCache, 2);
5117 if (!dst_.is(r0)) { 5107 __ Move(dst_, r0);
5118 __ mov(dst_, r0);
5119 }
5120 } 5108 }
5121 5109
5122 5110
5123 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) { 5111 void CodeGenerator::GenerateGetFromCache(ZoneList<Expression*>* args) {
5124 ASSERT_EQ(2, args->length()); 5112 ASSERT_EQ(2, args->length());
5125 5113
5126 ASSERT_NE(NULL, args->at(0)->AsLiteral()); 5114 ASSERT_NE(NULL, args->at(0)->AsLiteral());
5127 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value(); 5115 int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->handle()))->value();
5128 5116
5129 Handle<FixedArray> jsfunction_result_caches( 5117 Handle<FixedArray> jsfunction_result_caches(
5130 Top::global_context()->jsfunction_result_caches()); 5118 Top::global_context()->jsfunction_result_caches());
5131 if (jsfunction_result_caches->length() <= cache_id) { 5119 if (jsfunction_result_caches->length() <= cache_id) {
5132 __ Abort("Attempt to use undefined cache."); 5120 __ Abort("Attempt to use undefined cache.");
5133 frame_->EmitPushRoot(Heap::kUndefinedValueRootIndex); 5121 frame_->EmitPushRoot(Heap::kUndefinedValueRootIndex);
5134 return; 5122 return;
5135 } 5123 }
5136 5124
5137 Load(args->at(1)); 5125 Load(args->at(1));
5138 5126
5139 VirtualFrame::SpilledScope spilled_scope(frame_); 5127 frame_->PopToR1();
5128 frame_->SpillAll();
5129 Register key = r1; // Just poped to r1
5130 Register result = r0; // Free, as frame has just been spilled.
5131 Register scratch1 = VirtualFrame::scratch0();
5132 Register scratch2 = VirtualFrame::scratch1();
5140 5133
5141 frame_->EmitPop(r2); 5134 __ ldr(scratch1, ContextOperand(cp, Context::GLOBAL_INDEX));
5135 __ ldr(scratch1,
5136 FieldMemOperand(scratch1, GlobalObject::kGlobalContextOffset));
5137 __ ldr(scratch1,
5138 ContextOperand(scratch1, Context::JSFUNCTION_RESULT_CACHES_INDEX));
5139 __ ldr(scratch1,
5140 FieldMemOperand(scratch1, FixedArray::OffsetOfElementAt(cache_id)));
5142 5141
5143 __ ldr(r1, ContextOperand(cp, Context::GLOBAL_INDEX)); 5142 DeferredSearchCache* deferred =
5144 __ ldr(r1, FieldMemOperand(r1, GlobalObject::kGlobalContextOffset)); 5143 new DeferredSearchCache(result, scratch1, key);
5145 __ ldr(r1, ContextOperand(r1, Context::JSFUNCTION_RESULT_CACHES_INDEX));
5146 __ ldr(r1, FieldMemOperand(r1, FixedArray::OffsetOfElementAt(cache_id)));
5147
5148 DeferredSearchCache* deferred = new DeferredSearchCache(r0, r1, r2);
5149 5144
5150 const int kFingerOffset = 5145 const int kFingerOffset =
5151 FixedArray::OffsetOfElementAt(JSFunctionResultCache::kFingerIndex); 5146 FixedArray::OffsetOfElementAt(JSFunctionResultCache::kFingerIndex);
5152 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 5147 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
5153 __ ldr(r0, FieldMemOperand(r1, kFingerOffset)); 5148 __ ldr(result, FieldMemOperand(scratch1, kFingerOffset));
5154 // r0 now holds finger offset as a smi. 5149 // result now holds finger offset as a smi.
5155 __ add(r3, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 5150 __ add(scratch2, scratch1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
5156 // r3 now points to the start of fixed array elements. 5151 // scratch2 now points to the start of fixed array elements.
5157 __ ldr(r0, MemOperand(r3, r0, LSL, kPointerSizeLog2 - kSmiTagSize, PreIndex)); 5152 __ ldr(result,
5158 // Note side effect of PreIndex: r3 now points to the key of the pair. 5153 MemOperand(
5159 __ cmp(r2, r0); 5154 scratch2, result, LSL, kPointerSizeLog2 - kSmiTagSize, PreIndex));
5155 // Note side effect of PreIndex: scratch2 now points to the key of the pair.
5156 __ cmp(key, result);
5160 deferred->Branch(ne); 5157 deferred->Branch(ne);
5161 5158
5162 __ ldr(r0, MemOperand(r3, kPointerSize)); 5159 __ ldr(result, MemOperand(scratch2, kPointerSize));
5163 5160
5164 deferred->BindExit(); 5161 deferred->BindExit();
5165 frame_->EmitPush(r0); 5162 frame_->EmitPush(result);
5166 } 5163 }
5167 5164
5168 5165
5169 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) { 5166 void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
5170 ASSERT_EQ(args->length(), 1); 5167 ASSERT_EQ(args->length(), 1);
5171 5168
5172 // Load the argument on the stack and jump to the runtime. 5169 // Load the argument on the stack and jump to the runtime.
5173 Load(args->at(0)); 5170 Load(args->at(0));
5174 5171
5175 NumberToStringStub stub; 5172 NumberToStringStub stub;
(...skipping 5272 matching lines...) Expand 10 before | Expand all | Expand 10 after
10448 call_helper.BeforeCall(masm); 10445 call_helper.BeforeCall(masm);
10449 __ Push(object_, index_); 10446 __ Push(object_, index_);
10450 __ push(index_); // Consumed by runtime conversion function. 10447 __ push(index_); // Consumed by runtime conversion function.
10451 if (index_flags_ == STRING_INDEX_IS_NUMBER) { 10448 if (index_flags_ == STRING_INDEX_IS_NUMBER) {
10452 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); 10449 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
10453 } else { 10450 } else {
10454 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); 10451 ASSERT(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX);
10455 // NumberToSmi discards numbers that are not exact integers. 10452 // NumberToSmi discards numbers that are not exact integers.
10456 __ CallRuntime(Runtime::kNumberToSmi, 1); 10453 __ CallRuntime(Runtime::kNumberToSmi, 1);
10457 } 10454 }
10458 if (!scratch_.is(r0)) { 10455 // Save the conversion result before the pop instructions below
10459 // Save the conversion result before the pop instructions below 10456 // have a chance to overwrite it.
10460 // have a chance to overwrite it. 10457 __ Move(scratch_, r0);
10461 __ mov(scratch_, r0);
10462 }
10463 __ pop(index_); 10458 __ pop(index_);
10464 __ pop(object_); 10459 __ pop(object_);
10465 // Reload the instance type. 10460 // Reload the instance type.
10466 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); 10461 __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
10467 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); 10462 __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
10468 call_helper.AfterCall(masm); 10463 call_helper.AfterCall(masm);
10469 // If index is still not a smi, it must be out of range. 10464 // If index is still not a smi, it must be out of range.
10470 __ BranchOnNotSmi(scratch_, index_out_of_range_); 10465 __ BranchOnNotSmi(scratch_, index_out_of_range_);
10471 // Otherwise, return to the fast path. 10466 // Otherwise, return to the fast path.
10472 __ jmp(&got_smi_index_); 10467 __ jmp(&got_smi_index_);
10473 10468
10474 // Call runtime. We get here when the receiver is a string and the 10469 // Call runtime. We get here when the receiver is a string and the
10475 // index is a number, but the code of getting the actual character 10470 // index is a number, but the code of getting the actual character
10476 // is too complex (e.g., when the string needs to be flattened). 10471 // is too complex (e.g., when the string needs to be flattened).
10477 __ bind(&call_runtime_); 10472 __ bind(&call_runtime_);
10478 call_helper.BeforeCall(masm); 10473 call_helper.BeforeCall(masm);
10479 __ Push(object_, index_); 10474 __ Push(object_, index_);
10480 __ CallRuntime(Runtime::kStringCharCodeAt, 2); 10475 __ CallRuntime(Runtime::kStringCharCodeAt, 2);
10481 if (!result_.is(r0)) { 10476 __ Move(result_, r0);
10482 __ mov(result_, r0);
10483 }
10484 call_helper.AfterCall(masm); 10477 call_helper.AfterCall(masm);
10485 __ jmp(&exit_); 10478 __ jmp(&exit_);
10486 10479
10487 __ Abort("Unexpected fallthrough from CharCodeAt slow case"); 10480 __ Abort("Unexpected fallthrough from CharCodeAt slow case");
10488 } 10481 }
10489 10482
10490 10483
10491 // ------------------------------------------------------------------------- 10484 // -------------------------------------------------------------------------
10492 // StringCharFromCodeGenerator 10485 // StringCharFromCodeGenerator
10493 10486
(...skipping 20 matching lines...) Expand all
10514 10507
10515 10508
10516 void StringCharFromCodeGenerator::GenerateSlow( 10509 void StringCharFromCodeGenerator::GenerateSlow(
10517 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { 10510 MacroAssembler* masm, const RuntimeCallHelper& call_helper) {
10518 __ Abort("Unexpected fallthrough to CharFromCode slow case"); 10511 __ Abort("Unexpected fallthrough to CharFromCode slow case");
10519 10512
10520 __ bind(&slow_case_); 10513 __ bind(&slow_case_);
10521 call_helper.BeforeCall(masm); 10514 call_helper.BeforeCall(masm);
10522 __ push(code_); 10515 __ push(code_);
10523 __ CallRuntime(Runtime::kCharFromCode, 1); 10516 __ CallRuntime(Runtime::kCharFromCode, 1);
10524 if (!result_.is(r0)) { 10517 __ Move(result_, r0);
10525 __ mov(result_, r0);
10526 }
10527 call_helper.AfterCall(masm); 10518 call_helper.AfterCall(masm);
10528 __ jmp(&exit_); 10519 __ jmp(&exit_);
10529 10520
10530 __ Abort("Unexpected fallthrough from CharFromCode slow case"); 10521 __ Abort("Unexpected fallthrough from CharFromCode slow case");
10531 } 10522 }
10532 10523
10533 10524
10534 // ------------------------------------------------------------------------- 10525 // -------------------------------------------------------------------------
10535 // StringCharAtGenerator 10526 // StringCharAtGenerator
10536 10527
(...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after
11445 __ bind(&string_add_runtime); 11436 __ bind(&string_add_runtime);
11446 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 11437 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
11447 } 11438 }
11448 11439
11449 11440
11450 #undef __ 11441 #undef __
11451 11442
11452 } } // namespace v8::internal 11443 } } // namespace v8::internal
11453 11444
11454 #endif // V8_TARGET_ARCH_ARM 11445 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698