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

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

Issue 1663323003: [fullcode] Change fullcode to compile finally using the token approach. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Address review comments Created 4 years, 10 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
« no previous file with comments | « src/compiler/ast-graph-builder.cc ('k') | src/full-codegen/arm64/full-codegen-arm64.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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_ARM 5 #if V8_TARGET_ARCH_ARM
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
11 #include "src/debug/debug.h" 11 #include "src/debug/debug.h"
12 #include "src/full-codegen/full-codegen.h" 12 #include "src/full-codegen/full-codegen.h"
13 #include "src/ic/ic.h" 13 #include "src/ic/ic.h"
14 #include "src/parsing/parser.h" 14 #include "src/parsing/parser.h"
15 15
16 #include "src/arm/code-stubs-arm.h" 16 #include "src/arm/code-stubs-arm.h"
17 #include "src/arm/macro-assembler-arm.h" 17 #include "src/arm/macro-assembler-arm.h"
18 18
19 namespace v8 { 19 namespace v8 {
20 namespace internal { 20 namespace internal {
21 21
22 #define __ ACCESS_MASM(masm_) 22 #define __ ACCESS_MASM(masm())
23
24 23
25 // A patch site is a location in the code which it is possible to patch. This 24 // A patch site is a location in the code which it is possible to patch. This
26 // class has a number of methods to emit the code which is patchable and the 25 // class has a number of methods to emit the code which is patchable and the
27 // method EmitPatchInfo to record a marker back to the patchable code. This 26 // method EmitPatchInfo to record a marker back to the patchable code. This
28 // marker is a cmp rx, #yyy instruction, and x * 0x00000fff + yyy (raw 12 bit 27 // marker is a cmp rx, #yyy instruction, and x * 0x00000fff + yyy (raw 12 bit
29 // immediate value is used) is the delta from the pc to the first instruction of 28 // immediate value is used) is the delta from the pc to the first instruction of
30 // the patchable code. 29 // the patchable code.
31 class JumpPatchSite BASE_EMBEDDED { 30 class JumpPatchSite BASE_EMBEDDED {
32 public: 31 public:
33 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) { 32 explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 __ cmp_raw_immediate(reg, delta_to_patch_site % kOff12Mask); 69 __ cmp_raw_immediate(reg, delta_to_patch_site % kOff12Mask);
71 #ifdef DEBUG 70 #ifdef DEBUG
72 info_emitted_ = true; 71 info_emitted_ = true;
73 #endif 72 #endif
74 } else { 73 } else {
75 __ nop(); // Signals no inlined code. 74 __ nop(); // Signals no inlined code.
76 } 75 }
77 } 76 }
78 77
79 private: 78 private:
79 MacroAssembler* masm() { return masm_; }
80 MacroAssembler* masm_; 80 MacroAssembler* masm_;
81 Label patch_site_; 81 Label patch_site_;
82 #ifdef DEBUG 82 #ifdef DEBUG
83 bool info_emitted_; 83 bool info_emitted_;
84 #endif 84 #endif
85 }; 85 };
86 86
87 87
88 // Generate code for a JS function. On entry to the function the receiver 88 // Generate code for a JS function. On entry to the function the receiver
89 // and arguments have been pushed on the stack left to right. The actual 89 // and arguments have been pushed on the stack left to right. The actual
(...skipping 1847 matching lines...) Expand 10 before | Expand all | Expand 10 after
1937 __ bind(&continuation); 1937 __ bind(&continuation);
1938 // When we arrive here, the stack top is the resume mode and 1938 // When we arrive here, the stack top is the resume mode and
1939 // result_register() holds the input value (the argument given to the 1939 // result_register() holds the input value (the argument given to the
1940 // respective resume operation). 1940 // respective resume operation).
1941 __ RecordGeneratorContinuation(); 1941 __ RecordGeneratorContinuation();
1942 __ pop(r1); 1942 __ pop(r1);
1943 __ cmp(r1, Operand(Smi::FromInt(JSGeneratorObject::RETURN))); 1943 __ cmp(r1, Operand(Smi::FromInt(JSGeneratorObject::RETURN)));
1944 __ b(ne, &resume); 1944 __ b(ne, &resume);
1945 __ push(result_register()); 1945 __ push(result_register());
1946 EmitCreateIteratorResult(true); 1946 EmitCreateIteratorResult(true);
1947 EmitUnwindBeforeReturn(); 1947 EmitUnwindAndReturn();
1948 EmitReturnSequence();
1949 1948
1950 __ bind(&suspend); 1949 __ bind(&suspend);
1951 VisitForAccumulatorValue(expr->generator_object()); 1950 VisitForAccumulatorValue(expr->generator_object());
1952 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); 1951 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
1953 __ mov(r1, Operand(Smi::FromInt(continuation.pos()))); 1952 __ mov(r1, Operand(Smi::FromInt(continuation.pos())));
1954 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset)); 1953 __ str(r1, FieldMemOperand(r0, JSGeneratorObject::kContinuationOffset));
1955 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset)); 1954 __ str(cp, FieldMemOperand(r0, JSGeneratorObject::kContextOffset));
1956 __ mov(r1, cp); 1955 __ mov(r1, cp);
1957 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2, 1956 __ RecordWriteField(r0, JSGeneratorObject::kContextOffset, r1, r2,
1958 kLRHasBeenSaved, kDontSaveFPRegs); 1957 kLRHasBeenSaved, kDontSaveFPRegs);
1959 __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); 1958 __ add(r1, fp, Operand(StandardFrameConstants::kExpressionsOffset));
1960 __ cmp(sp, r1); 1959 __ cmp(sp, r1);
1961 __ b(eq, &post_runtime); 1960 __ b(eq, &post_runtime);
1962 __ push(r0); // generator object 1961 __ push(r0); // generator object
1963 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1962 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1964 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1963 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1965 __ bind(&post_runtime); 1964 __ bind(&post_runtime);
1966 __ pop(result_register()); 1965 __ pop(result_register());
1967 EmitReturnSequence(); 1966 EmitReturnSequence();
1968 1967
1969 __ bind(&resume); 1968 __ bind(&resume);
1970 context()->Plug(result_register()); 1969 context()->Plug(result_register());
1971 break; 1970 break;
1972 } 1971 }
1973 1972
1974 case Yield::kFinal: { 1973 case Yield::kFinal: {
1975 // Pop value from top-of-stack slot, box result into result register. 1974 // Pop value from top-of-stack slot, box result into result register.
1976 EmitCreateIteratorResult(true); 1975 EmitCreateIteratorResult(true);
1977 EmitUnwindBeforeReturn(); 1976 EmitUnwindAndReturn();
1978 EmitReturnSequence();
1979 break; 1977 break;
1980 } 1978 }
1981 1979
1982 case Yield::kDelegating: { 1980 case Yield::kDelegating: {
1983 VisitForStackValue(expr->generator_object()); 1981 VisitForStackValue(expr->generator_object());
1984 1982
1985 // Initial stack layout is as follows: 1983 // Initial stack layout is as follows:
1986 // [sp + 1 * kPointerSize] iter 1984 // [sp + 1 * kPointerSize] iter
1987 // [sp + 0 * kPointerSize] g 1985 // [sp + 0 * kPointerSize] g
1988 1986
(...skipping 2660 matching lines...) Expand 10 before | Expand all | Expand 10 after
4649 } 4647 }
4650 __ push(ip); 4648 __ push(ip);
4651 } 4649 }
4652 4650
4653 4651
4654 // ---------------------------------------------------------------------------- 4652 // ----------------------------------------------------------------------------
4655 // Non-local control flow support. 4653 // Non-local control flow support.
4656 4654
4657 void FullCodeGenerator::EnterFinallyBlock() { 4655 void FullCodeGenerator::EnterFinallyBlock() {
4658 DCHECK(!result_register().is(r1)); 4656 DCHECK(!result_register().is(r1));
4659 // Store result register while executing finally block.
4660 __ push(result_register());
4661 // Cook return address in link register to stack (smi encoded Code* delta)
4662 __ sub(r1, lr, Operand(masm_->CodeObject()));
4663 __ SmiTag(r1);
4664
4665 // Store result register while executing finally block.
4666 __ push(r1);
4667
4668 // Store pending message while executing finally block. 4657 // Store pending message while executing finally block.
4669 ExternalReference pending_message_obj = 4658 ExternalReference pending_message_obj =
4670 ExternalReference::address_of_pending_message_obj(isolate()); 4659 ExternalReference::address_of_pending_message_obj(isolate());
4671 __ mov(ip, Operand(pending_message_obj)); 4660 __ mov(ip, Operand(pending_message_obj));
4672 __ ldr(r1, MemOperand(ip)); 4661 __ ldr(r1, MemOperand(ip));
4673 __ push(r1); 4662 __ push(r1);
4674 4663
4675 ClearPendingMessage(); 4664 ClearPendingMessage();
4676 } 4665 }
4677 4666
4678 4667
4679 void FullCodeGenerator::ExitFinallyBlock() { 4668 void FullCodeGenerator::ExitFinallyBlock() {
4680 DCHECK(!result_register().is(r1)); 4669 DCHECK(!result_register().is(r1));
4681 // Restore pending message from stack. 4670 // Restore pending message from stack.
4682 __ pop(r1); 4671 __ pop(r1);
4683 ExternalReference pending_message_obj = 4672 ExternalReference pending_message_obj =
4684 ExternalReference::address_of_pending_message_obj(isolate()); 4673 ExternalReference::address_of_pending_message_obj(isolate());
4685 __ mov(ip, Operand(pending_message_obj)); 4674 __ mov(ip, Operand(pending_message_obj));
4686 __ str(r1, MemOperand(ip)); 4675 __ str(r1, MemOperand(ip));
4687
4688 // Restore result register from stack.
4689 __ pop(r1);
4690
4691 // Uncook return address and return.
4692 __ pop(result_register());
4693 __ SmiUntag(r1);
4694 __ add(pc, r1, Operand(masm_->CodeObject()));
4695 } 4676 }
4696 4677
4697 4678
4698 void FullCodeGenerator::ClearPendingMessage() { 4679 void FullCodeGenerator::ClearPendingMessage() {
4699 DCHECK(!result_register().is(r1)); 4680 DCHECK(!result_register().is(r1));
4700 ExternalReference pending_message_obj = 4681 ExternalReference pending_message_obj =
4701 ExternalReference::address_of_pending_message_obj(isolate()); 4682 ExternalReference::address_of_pending_message_obj(isolate());
4702 __ LoadRoot(r1, Heap::kTheHoleValueRootIndex); 4683 __ LoadRoot(r1, Heap::kTheHoleValueRootIndex);
4703 __ mov(ip, Operand(pending_message_obj)); 4684 __ mov(ip, Operand(pending_message_obj));
4704 __ str(r1, MemOperand(ip)); 4685 __ str(r1, MemOperand(ip));
4705 } 4686 }
4706 4687
4707 4688
4708 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) { 4689 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) {
4709 DCHECK(!slot.IsInvalid()); 4690 DCHECK(!slot.IsInvalid());
4710 __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(), 4691 __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(),
4711 Operand(SmiFromSlot(slot))); 4692 Operand(SmiFromSlot(slot)));
4712 } 4693 }
4713 4694
4695 void FullCodeGenerator::DeferredCommands::EmitCommands() {
4696 DCHECK(!result_register().is(r1));
4697 __ Pop(result_register()); // Restore the accumulator.
4698 __ Pop(r1); // Get the token.
4699 for (DeferredCommand cmd : commands_) {
4700 Label skip;
4701 __ cmp(r1, Operand(Smi::FromInt(cmd.token)));
4702 __ b(ne, &skip);
4703 switch (cmd.command) {
4704 case kReturn:
4705 codegen_->EmitUnwindAndReturn();
4706 break;
4707 case kThrow:
4708 __ Push(result_register());
4709 __ CallRuntime(Runtime::kReThrow);
4710 break;
4711 case kContinue:
4712 codegen_->EmitContinue(cmd.target);
4713 break;
4714 case kBreak:
4715 codegen_->EmitBreak(cmd.target);
4716 break;
4717 }
4718 __ bind(&skip);
4719 }
4720 }
4714 4721
4715 #undef __ 4722 #undef __
4716 4723
4717 4724
4718 static Address GetInterruptImmediateLoadAddress(Address pc) { 4725 static Address GetInterruptImmediateLoadAddress(Address pc) {
4719 Address load_address = pc - 2 * Assembler::kInstrSize; 4726 Address load_address = pc - 2 * Assembler::kInstrSize;
4720 if (!FLAG_enable_embedded_constant_pool) { 4727 if (!FLAG_enable_embedded_constant_pool) {
4721 DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(load_address))); 4728 DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(load_address)));
4722 } else if (Assembler::IsLdrPpRegOffset(Memory::int32_at(load_address))) { 4729 } else if (Assembler::IsLdrPpRegOffset(Memory::int32_at(load_address))) {
4723 // This is an extended constant pool lookup. 4730 // This is an extended constant pool lookup.
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
4852 DCHECK(interrupt_address == 4859 DCHECK(interrupt_address ==
4853 isolate->builtins()->OsrAfterStackCheck()->entry()); 4860 isolate->builtins()->OsrAfterStackCheck()->entry());
4854 return OSR_AFTER_STACK_CHECK; 4861 return OSR_AFTER_STACK_CHECK;
4855 } 4862 }
4856 4863
4857 4864
4858 } // namespace internal 4865 } // namespace internal
4859 } // namespace v8 4866 } // namespace v8
4860 4867
4861 #endif // V8_TARGET_ARCH_ARM 4868 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.cc ('k') | src/full-codegen/arm64/full-codegen-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698