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

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

Issue 44313002: Try to use STMDB/LDMIA instead of LDR/STR sequences whenever possible. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 1 month 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/arm/code-stubs-arm.cc ('k') | src/arm/ic-arm.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 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 598 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 __ bind(&done); 609 __ bind(&done);
610 } 610 }
611 611
612 612
613 void FullCodeGenerator::StackValueContext::Plug( 613 void FullCodeGenerator::StackValueContext::Plug(
614 Label* materialize_true, 614 Label* materialize_true,
615 Label* materialize_false) const { 615 Label* materialize_false) const {
616 Label done; 616 Label done;
617 __ bind(materialize_true); 617 __ bind(materialize_true);
618 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 618 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
619 __ push(ip);
620 __ jmp(&done); 619 __ jmp(&done);
621 __ bind(materialize_false); 620 __ bind(materialize_false);
622 __ LoadRoot(ip, Heap::kFalseValueRootIndex); 621 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
622 __ bind(&done);
623 __ push(ip); 623 __ push(ip);
624 __ bind(&done);
625 } 624 }
626 625
627 626
628 void FullCodeGenerator::TestContext::Plug(Label* materialize_true, 627 void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
629 Label* materialize_false) const { 628 Label* materialize_false) const {
630 ASSERT(materialize_true == true_label_); 629 ASSERT(materialize_true == true_label_);
631 ASSERT(materialize_false == false_label_); 630 ASSERT(materialize_false == false_label_);
632 } 631 }
633 632
634 633
(...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after
1593 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); 1592 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
1594 __ mov(r5, r0); 1593 __ mov(r5, r0);
1595 1594
1596 __ bind(&materialized); 1595 __ bind(&materialized);
1597 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize; 1596 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
1598 Label allocated, runtime_allocate; 1597 Label allocated, runtime_allocate;
1599 __ Allocate(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT); 1598 __ Allocate(size, r0, r2, r3, &runtime_allocate, TAG_OBJECT);
1600 __ jmp(&allocated); 1599 __ jmp(&allocated);
1601 1600
1602 __ bind(&runtime_allocate); 1601 __ bind(&runtime_allocate);
1603 __ push(r5);
1604 __ mov(r0, Operand(Smi::FromInt(size))); 1602 __ mov(r0, Operand(Smi::FromInt(size)));
1605 __ push(r0); 1603 __ Push(r5, r0);
1606 __ CallRuntime(Runtime::kAllocateInNewSpace, 1); 1604 __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
1607 __ pop(r5); 1605 __ pop(r5);
1608 1606
1609 __ bind(&allocated); 1607 __ bind(&allocated);
1610 // After this, registers are used as follows: 1608 // After this, registers are used as follows:
1611 // r0: Newly allocated regexp. 1609 // r0: Newly allocated regexp.
1612 // r5: Materialized regexp. 1610 // r5: Materialized regexp.
1613 // r2: temp. 1611 // r2: temp.
1614 __ CopyFields(r0, r5, d0, size / kPointerSize); 1612 __ CopyFields(r0, r5, d0, size / kPointerSize);
1615 context()->Plug(r0); 1613 context()->Plug(r0);
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
2032 Label l_next, l_call, l_loop; 2030 Label l_next, l_call, l_loop;
2033 // Initial send value is undefined. 2031 // Initial send value is undefined.
2034 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 2032 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
2035 __ b(&l_next); 2033 __ b(&l_next);
2036 2034
2037 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 2035 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
2038 __ bind(&l_catch); 2036 __ bind(&l_catch);
2039 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 2037 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
2040 __ LoadRoot(r2, Heap::kthrow_stringRootIndex); // "throw" 2038 __ LoadRoot(r2, Heap::kthrow_stringRootIndex); // "throw"
2041 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter 2039 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter
2042 __ push(r3); // iter 2040 __ Push(r3, r0); // iter, exception
2043 __ push(r0); // exception
2044 __ jmp(&l_call); 2041 __ jmp(&l_call);
2045 2042
2046 // try { received = %yield result } 2043 // try { received = %yield result }
2047 // Shuffle the received result above a try handler and yield it without 2044 // Shuffle the received result above a try handler and yield it without
2048 // re-boxing. 2045 // re-boxing.
2049 __ bind(&l_try); 2046 __ bind(&l_try);
2050 __ pop(r0); // result 2047 __ pop(r0); // result
2051 __ PushTryHandler(StackHandler::CATCH, expr->index()); 2048 __ PushTryHandler(StackHandler::CATCH, expr->index());
2052 const int handler_size = StackHandlerConstants::kSize; 2049 const int handler_size = StackHandlerConstants::kSize;
2053 __ push(r0); // result 2050 __ push(r0); // result
(...skipping 15 matching lines...) Expand all
2069 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2066 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2070 __ pop(r0); // result 2067 __ pop(r0); // result
2071 EmitReturnSequence(); 2068 EmitReturnSequence();
2072 __ bind(&l_resume); // received in r0 2069 __ bind(&l_resume); // received in r0
2073 __ PopTryHandler(); 2070 __ PopTryHandler();
2074 2071
2075 // receiver = iter; f = 'next'; arg = received; 2072 // receiver = iter; f = 'next'; arg = received;
2076 __ bind(&l_next); 2073 __ bind(&l_next);
2077 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" 2074 __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next"
2078 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter 2075 __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter
2079 __ push(r3); // iter 2076 __ Push(r3, r0); // iter, received
2080 __ push(r0); // received
2081 2077
2082 // result = receiver[f](arg); 2078 // result = receiver[f](arg);
2083 __ bind(&l_call); 2079 __ bind(&l_call);
2084 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1); 2080 Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1);
2085 CallIC(ic); 2081 CallIC(ic);
2086 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2082 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2087 2083
2088 // if (!result.done) goto l_try; 2084 // if (!result.done) goto l_try;
2089 __ bind(&l_loop); 2085 __ bind(&l_loop);
2090 __ push(r0); // save result 2086 __ push(r0); // save result
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2146 __ push(r2); 2142 __ push(r2);
2147 __ jmp(&push_argument_holes); 2143 __ jmp(&push_argument_holes);
2148 2144
2149 // Enter a new JavaScript frame, and initialize its slots as they were when 2145 // Enter a new JavaScript frame, and initialize its slots as they were when
2150 // the generator was suspended. 2146 // the generator was suspended.
2151 Label resume_frame; 2147 Label resume_frame;
2152 __ bind(&push_frame); 2148 __ bind(&push_frame);
2153 __ bl(&resume_frame); 2149 __ bl(&resume_frame);
2154 __ jmp(&done); 2150 __ jmp(&done);
2155 __ bind(&resume_frame); 2151 __ bind(&resume_frame);
2156 __ push(lr); // Return address. 2152 // lr = return address.
2157 __ push(fp); // Caller's frame pointer. 2153 // fp = caller's frame pointer.
2158 __ mov(fp, sp); 2154 // cp = callee's context,
2159 __ push(cp); // Callee's context. 2155 // r4 = callee's JS function.
2160 __ push(r4); // Callee's JS Function. 2156 __ Push(lr, fp, cp, r4);
2157 // Adjust FP to point to saved FP.
2158 __ add(fp, sp, Operand(2 * kPointerSize));
2161 2159
2162 // Load the operand stack size. 2160 // Load the operand stack size.
2163 __ ldr(r3, FieldMemOperand(r1, JSGeneratorObject::kOperandStackOffset)); 2161 __ ldr(r3, FieldMemOperand(r1, JSGeneratorObject::kOperandStackOffset));
2164 __ ldr(r3, FieldMemOperand(r3, FixedArray::kLengthOffset)); 2162 __ ldr(r3, FieldMemOperand(r3, FixedArray::kLengthOffset));
2165 __ SmiUntag(r3); 2163 __ SmiUntag(r3);
2166 2164
2167 // If we are sending a value and there is no operand stack, we can jump back 2165 // If we are sending a value and there is no operand stack, we can jump back
2168 // in directly. 2166 // in directly.
2169 if (resume_mode == JSGeneratorObject::NEXT) { 2167 if (resume_mode == JSGeneratorObject::NEXT) {
2170 Label slow_resume; 2168 Label slow_resume;
(...skipping 11 matching lines...) Expand all
2182 2180
2183 // Otherwise, we push holes for the operand stack and call the runtime to fix 2181 // Otherwise, we push holes for the operand stack and call the runtime to fix
2184 // up the stack and the handlers. 2182 // up the stack and the handlers.
2185 Label push_operand_holes, call_resume; 2183 Label push_operand_holes, call_resume;
2186 __ bind(&push_operand_holes); 2184 __ bind(&push_operand_holes);
2187 __ sub(r3, r3, Operand(1), SetCC); 2185 __ sub(r3, r3, Operand(1), SetCC);
2188 __ b(mi, &call_resume); 2186 __ b(mi, &call_resume);
2189 __ push(r2); 2187 __ push(r2);
2190 __ b(&push_operand_holes); 2188 __ b(&push_operand_holes);
2191 __ bind(&call_resume); 2189 __ bind(&call_resume);
2192 __ push(r1); 2190 ASSERT(!result_register().is(r1));
2193 __ push(result_register()); 2191 __ Push(r1, result_register());
2194 __ Push(Smi::FromInt(resume_mode)); 2192 __ Push(Smi::FromInt(resume_mode));
2195 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3); 2193 __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
2196 // Not reached: the runtime call returns elsewhere. 2194 // Not reached: the runtime call returns elsewhere.
2197 __ stop("not-reached"); 2195 __ stop("not-reached");
2198 2196
2199 // Throw error if we attempt to operate on a running generator. 2197 // Throw error if we attempt to operate on a running generator.
2200 __ bind(&wrong_state); 2198 __ bind(&wrong_state);
2201 __ push(r1); 2199 __ push(r1);
2202 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1); 2200 __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
2203 2201
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
2405 ? isolate()->builtins()->StoreIC_Initialize() 2403 ? isolate()->builtins()->StoreIC_Initialize()
2406 : isolate()->builtins()->StoreIC_Initialize_Strict(); 2404 : isolate()->builtins()->StoreIC_Initialize_Strict();
2407 CallIC(ic); 2405 CallIC(ic);
2408 break; 2406 break;
2409 } 2407 }
2410 case KEYED_PROPERTY: { 2408 case KEYED_PROPERTY: {
2411 __ push(r0); // Preserve value. 2409 __ push(r0); // Preserve value.
2412 VisitForStackValue(prop->obj()); 2410 VisitForStackValue(prop->obj());
2413 VisitForAccumulatorValue(prop->key()); 2411 VisitForAccumulatorValue(prop->key());
2414 __ mov(r1, r0); 2412 __ mov(r1, r0);
2415 __ pop(r2); 2413 __ Pop(r0, r2); // r0 = restored value.
2416 __ pop(r0); // Restore value.
2417 Handle<Code> ic = is_classic_mode() 2414 Handle<Code> ic = is_classic_mode()
2418 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2415 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2419 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2416 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2420 CallIC(ic); 2417 CallIC(ic);
2421 break; 2418 break;
2422 } 2419 }
2423 } 2420 }
2424 context()->Plug(r0); 2421 context()->Plug(r0);
2425 } 2422 }
2426 2423
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
2540 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2537 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2541 context()->Plug(r0); 2538 context()->Plug(r0);
2542 } 2539 }
2543 2540
2544 2541
2545 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2542 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2546 // Assignment to a property, using a keyed store IC. 2543 // Assignment to a property, using a keyed store IC.
2547 2544
2548 // Record source code position before IC call. 2545 // Record source code position before IC call.
2549 SetSourcePosition(expr->position()); 2546 SetSourcePosition(expr->position());
2550 __ pop(r1); // Key. 2547 __ Pop(r2, r1); // r1 = key.
2551 __ pop(r2);
2552 2548
2553 Handle<Code> ic = is_classic_mode() 2549 Handle<Code> ic = is_classic_mode()
2554 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2550 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2555 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2551 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2556 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId()); 2552 CallIC(ic, RelocInfo::CODE_TARGET, expr->AssignmentFeedbackId());
2557 2553
2558 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2554 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2559 context()->Plug(r0); 2555 context()->Plug(r0);
2560 } 2556 }
2561 2557
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2670 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); 2666 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
2671 __ CallStub(&stub, expr->CallFeedbackId()); 2667 __ CallStub(&stub, expr->CallFeedbackId());
2672 RecordJSReturnSite(expr); 2668 RecordJSReturnSite(expr);
2673 // Restore context register. 2669 // Restore context register.
2674 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2670 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2675 context()->DropAndPlug(1, r0); 2671 context()->DropAndPlug(1, r0);
2676 } 2672 }
2677 2673
2678 2674
2679 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) { 2675 void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
2680 // Push copy of the first argument or undefined if it doesn't exist. 2676 // r4: copy of the first argument or undefined if it doesn't exist.
2681 if (arg_count > 0) { 2677 if (arg_count > 0) {
2682 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); 2678 __ ldr(r4, MemOperand(sp, arg_count * kPointerSize));
2683 } else { 2679 } else {
2684 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 2680 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
2685 } 2681 }
2686 __ push(r1);
2687 2682
2688 // Push the receiver of the enclosing function. 2683 // r3: the receiver of the enclosing function.
2689 int receiver_offset = 2 + info_->scope()->num_parameters(); 2684 int receiver_offset = 2 + info_->scope()->num_parameters();
2690 __ ldr(r1, MemOperand(fp, receiver_offset * kPointerSize)); 2685 __ ldr(r3, MemOperand(fp, receiver_offset * kPointerSize));
2691 __ push(r1);
2692 // Push the language mode.
2693 __ mov(r1, Operand(Smi::FromInt(language_mode())));
2694 __ push(r1);
2695 2686
2696 // Push the start position of the scope the calls resides in. 2687 // r2: the language mode.
2688 __ mov(r2, Operand(Smi::FromInt(language_mode())));
2689
2690 // r1: the start position of the scope the calls resides in.
2697 __ mov(r1, Operand(Smi::FromInt(scope()->start_position()))); 2691 __ mov(r1, Operand(Smi::FromInt(scope()->start_position())));
2698 __ push(r1);
2699 2692
2700 // Do the runtime call. 2693 // Do the runtime call.
2694 __ Push(r4, r3, r2, r1);
2701 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2695 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2702 } 2696 }
2703 2697
2704 2698
2705 void FullCodeGenerator::VisitCall(Call* expr) { 2699 void FullCodeGenerator::VisitCall(Call* expr) {
2706 #ifdef DEBUG 2700 #ifdef DEBUG
2707 // We want to verify that RecordJSReturnSite gets called on all paths 2701 // We want to verify that RecordJSReturnSite gets called on all paths
2708 // through this function. Avoid early returns. 2702 // through this function. Avoid early returns.
2709 expr->return_is_recorded_ = false; 2703 expr->return_is_recorded_ = false;
2710 #endif 2704 #endif
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2764 2758
2765 { PreservePositionScope scope(masm()->positions_recorder()); 2759 { PreservePositionScope scope(masm()->positions_recorder());
2766 // Generate code for loading from variables potentially shadowed 2760 // Generate code for loading from variables potentially shadowed
2767 // by eval-introduced variables. 2761 // by eval-introduced variables.
2768 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done); 2762 EmitDynamicLookupFastCase(proxy->var(), NOT_INSIDE_TYPEOF, &slow, &done);
2769 } 2763 }
2770 2764
2771 __ bind(&slow); 2765 __ bind(&slow);
2772 // Call the runtime to find the function to call (returned in r0) 2766 // Call the runtime to find the function to call (returned in r0)
2773 // and the object holding it (returned in edx). 2767 // and the object holding it (returned in edx).
2774 __ push(context_register()); 2768 ASSERT(!context_register().is(r2));
2775 __ mov(r2, Operand(proxy->name())); 2769 __ mov(r2, Operand(proxy->name()));
2776 __ push(r2); 2770 __ Push(context_register(), r2);
2777 __ CallRuntime(Runtime::kLoadContextSlot, 2); 2771 __ CallRuntime(Runtime::kLoadContextSlot, 2);
2778 __ Push(r0, r1); // Function, receiver. 2772 __ Push(r0, r1); // Function, receiver.
2779 2773
2780 // If fast case code has been generated, emit code to push the 2774 // If fast case code has been generated, emit code to push the
2781 // function and receiver and have the slow path jump around this 2775 // function and receiver and have the slow path jump around this
2782 // code. 2776 // code.
2783 if (done.is_linked()) { 2777 if (done.is_linked()) {
2784 Label call; 2778 Label call;
2785 __ b(&call); 2779 __ b(&call);
2786 __ bind(&done); 2780 __ bind(&done);
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after
3483 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) { 3477 void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
3484 ZoneList<Expression*>* args = expr->arguments(); 3478 ZoneList<Expression*>* args = expr->arguments();
3485 ASSERT_EQ(3, args->length()); 3479 ASSERT_EQ(3, args->length());
3486 3480
3487 Register string = r0; 3481 Register string = r0;
3488 Register index = r1; 3482 Register index = r1;
3489 Register value = r2; 3483 Register value = r2;
3490 3484
3491 VisitForStackValue(args->at(1)); // index 3485 VisitForStackValue(args->at(1)); // index
3492 VisitForStackValue(args->at(2)); // value 3486 VisitForStackValue(args->at(2)); // value
3493 __ pop(value); 3487 __ Pop(index, value);
3494 __ pop(index);
3495 VisitForAccumulatorValue(args->at(0)); // string 3488 VisitForAccumulatorValue(args->at(0)); // string
3496 3489
3497 if (FLAG_debug_code) { 3490 if (FLAG_debug_code) {
3498 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag; 3491 static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
3499 EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type); 3492 EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type);
3500 } 3493 }
3501 3494
3502 __ SmiUntag(value, value); 3495 __ SmiUntag(value, value);
3503 __ add(ip, 3496 __ add(ip,
3504 string, 3497 string,
3505 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag)); 3498 Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
3506 __ strb(value, MemOperand(ip, index, LSR, kSmiTagSize)); 3499 __ strb(value, MemOperand(ip, index, LSR, kSmiTagSize));
3507 context()->Plug(string); 3500 context()->Plug(string);
3508 } 3501 }
3509 3502
3510 3503
3511 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) { 3504 void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
3512 ZoneList<Expression*>* args = expr->arguments(); 3505 ZoneList<Expression*>* args = expr->arguments();
3513 ASSERT_EQ(3, args->length()); 3506 ASSERT_EQ(3, args->length());
3514 3507
3515 Register string = r0; 3508 Register string = r0;
3516 Register index = r1; 3509 Register index = r1;
3517 Register value = r2; 3510 Register value = r2;
3518 3511
3519 VisitForStackValue(args->at(1)); // index 3512 VisitForStackValue(args->at(1)); // index
3520 VisitForStackValue(args->at(2)); // value 3513 VisitForStackValue(args->at(2)); // value
3521 __ pop(value); 3514 __ Pop(index, value);
3522 __ pop(index);
3523 VisitForAccumulatorValue(args->at(0)); // string 3515 VisitForAccumulatorValue(args->at(0)); // string
3524 3516
3525 if (FLAG_debug_code) { 3517 if (FLAG_debug_code) {
3526 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag; 3518 static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
3527 EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type); 3519 EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
3528 } 3520 }
3529 3521
3530 __ SmiUntag(value, value); 3522 __ SmiUntag(value, value);
3531 __ add(ip, 3523 __ add(ip,
3532 string, 3524 string,
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after
4256 __ Push(r2, r1, r0); 4248 __ Push(r2, r1, r0);
4257 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4249 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4258 context()->Plug(r0); 4250 context()->Plug(r0);
4259 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4251 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4260 // Result of deleting non-global, non-dynamic variables is false. 4252 // Result of deleting non-global, non-dynamic variables is false.
4261 // The subexpression does not have side effects. 4253 // The subexpression does not have side effects.
4262 context()->Plug(var->is_this()); 4254 context()->Plug(var->is_this());
4263 } else { 4255 } else {
4264 // Non-global variable. Call the runtime to try to delete from the 4256 // Non-global variable. Call the runtime to try to delete from the
4265 // context where the variable was introduced. 4257 // context where the variable was introduced.
4266 __ push(context_register()); 4258 ASSERT(!context_register().is(r2));
4267 __ mov(r2, Operand(var->name())); 4259 __ mov(r2, Operand(var->name()));
4268 __ push(r2); 4260 __ Push(context_register(), r2);
4269 __ CallRuntime(Runtime::kDeleteContextSlot, 2); 4261 __ CallRuntime(Runtime::kDeleteContextSlot, 2);
4270 context()->Plug(r0); 4262 context()->Plug(r0);
4271 } 4263 }
4272 } else { 4264 } else {
4273 // Result of deleting non-property, non-variable reference is true. 4265 // Result of deleting non-property, non-variable reference is true.
4274 // The subexpression may have side effects. 4266 // The subexpression may have side effects.
4275 VisitForEffect(expr->expression()); 4267 VisitForEffect(expr->expression());
4276 context()->Plug(true); 4268 context()->Plug(true);
4277 } 4269 }
4278 break; 4270 break;
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
4488 if (expr->is_postfix()) { 4480 if (expr->is_postfix()) {
4489 if (!context()->IsEffect()) { 4481 if (!context()->IsEffect()) {
4490 context()->PlugTOS(); 4482 context()->PlugTOS();
4491 } 4483 }
4492 } else { 4484 } else {
4493 context()->Plug(r0); 4485 context()->Plug(r0);
4494 } 4486 }
4495 break; 4487 break;
4496 } 4488 }
4497 case KEYED_PROPERTY: { 4489 case KEYED_PROPERTY: {
4498 __ pop(r1); // Key. 4490 __ Pop(r2, r1); // r1 = key. r2 = receiver.
4499 __ pop(r2); // Receiver.
4500 Handle<Code> ic = is_classic_mode() 4491 Handle<Code> ic = is_classic_mode()
4501 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4492 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4502 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4493 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4503 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId()); 4494 CallIC(ic, RelocInfo::CODE_TARGET, expr->CountStoreFeedbackId());
4504 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4495 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4505 if (expr->is_postfix()) { 4496 if (expr->is_postfix()) {
4506 if (!context()->IsEffect()) { 4497 if (!context()->IsEffect()) {
4507 context()->PlugTOS(); 4498 context()->PlugTOS();
4508 } 4499 }
4509 } else { 4500 } else {
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
4962 ASSERT(Memory::uint32_at(interrupt_address_pointer) == 4953 ASSERT(Memory::uint32_at(interrupt_address_pointer) ==
4963 reinterpret_cast<uint32_t>( 4954 reinterpret_cast<uint32_t>(
4964 isolate->builtins()->OsrAfterStackCheck()->entry())); 4955 isolate->builtins()->OsrAfterStackCheck()->entry()));
4965 return OSR_AFTER_STACK_CHECK; 4956 return OSR_AFTER_STACK_CHECK;
4966 } 4957 }
4967 4958
4968 4959
4969 } } // namespace v8::internal 4960 } } // namespace v8::internal
4970 4961
4971 #endif // V8_TARGET_ARCH_ARM 4962 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698