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

Side by Side Diff: src/full-codegen/mips/full-codegen-mips.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
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_MIPS 5 #if V8_TARGET_ARCH_MIPS
6 6
7 // Note on Mips implementation: 7 // Note on Mips implementation:
8 // 8 //
9 // The result_register() for mips is the 'v0' register, which is defined 9 // The result_register() for mips is the 'v0' register, which is defined
10 // by the ABI to contain function return values. However, the first 10 // by the ABI to contain function return values. However, the first
11 // parameter to a function is defined to be 'a0'. So there are many 11 // parameter to a function is defined to be 'a0'. So there are many
12 // places where we have to move a previous result in v0 to a0 for the 12 // places where we have to move a previous result in v0 to a0 for the
13 // next call: mov(a0, v0). This is not needed on the other architectures. 13 // next call: mov(a0, v0). This is not needed on the other architectures.
14 14
15 #include "src/ast/scopes.h" 15 #include "src/ast/scopes.h"
16 #include "src/code-factory.h" 16 #include "src/code-factory.h"
17 #include "src/code-stubs.h" 17 #include "src/code-stubs.h"
18 #include "src/codegen.h" 18 #include "src/codegen.h"
19 #include "src/debug/debug.h" 19 #include "src/debug/debug.h"
20 #include "src/full-codegen/full-codegen.h" 20 #include "src/full-codegen/full-codegen.h"
21 #include "src/ic/ic.h" 21 #include "src/ic/ic.h"
22 #include "src/parsing/parser.h" 22 #include "src/parsing/parser.h"
23 23
24 #include "src/mips/code-stubs-mips.h" 24 #include "src/mips/code-stubs-mips.h"
25 #include "src/mips/macro-assembler-mips.h" 25 #include "src/mips/macro-assembler-mips.h"
26 26
27 namespace v8 { 27 namespace v8 {
28 namespace internal { 28 namespace internal {
29 29
30 #define __ ACCESS_MASM(masm_) 30 #define __ ACCESS_MASM(masm())
31
32 31
33 // A patch site is a location in the code which it is possible to patch. This 32 // A patch site is a location in the code which it is possible to patch. This
34 // class has a number of methods to emit the code which is patchable and the 33 // class has a number of methods to emit the code which is patchable and the
35 // method EmitPatchInfo to record a marker back to the patchable code. This 34 // method EmitPatchInfo to record a marker back to the patchable code. This
36 // marker is a andi zero_reg, rx, #yyyy instruction, and rx * 0x0000ffff + yyyy 35 // marker is a andi zero_reg, rx, #yyyy instruction, and rx * 0x0000ffff + yyyy
37 // (raw 16 bit immediate value is used) is the delta from the pc to the first 36 // (raw 16 bit immediate value is used) is the delta from the pc to the first
38 // instruction of the patchable code. 37 // instruction of the patchable code.
39 // The marker instruction is effectively a NOP (dest is zero_reg) and will 38 // The marker instruction is effectively a NOP (dest is zero_reg) and will
40 // never be emitted by normal code. 39 // never be emitted by normal code.
41 class JumpPatchSite BASE_EMBEDDED { 40 class JumpPatchSite BASE_EMBEDDED {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 __ andi(zero_reg, reg, delta_to_patch_site % kImm16Mask); 78 __ andi(zero_reg, reg, delta_to_patch_site % kImm16Mask);
80 #ifdef DEBUG 79 #ifdef DEBUG
81 info_emitted_ = true; 80 info_emitted_ = true;
82 #endif 81 #endif
83 } else { 82 } else {
84 __ nop(); // Signals no inlined code. 83 __ nop(); // Signals no inlined code.
85 } 84 }
86 } 85 }
87 86
88 private: 87 private:
88 MacroAssembler* masm() { return masm_; }
89 MacroAssembler* masm_; 89 MacroAssembler* masm_;
90 Label patch_site_; 90 Label patch_site_;
91 #ifdef DEBUG 91 #ifdef DEBUG
92 bool info_emitted_; 92 bool info_emitted_;
93 #endif 93 #endif
94 }; 94 };
95 95
96 96
97 // Generate code for a JS function. On entry to the function the receiver 97 // Generate code for a JS function. On entry to the function the receiver
98 // and arguments have been pushed on the stack left to right. The actual 98 // and arguments have been pushed on the stack left to right. The actual
(...skipping 1836 matching lines...) Expand 10 before | Expand all | Expand 10 after
1935 __ bind(&continuation); 1935 __ bind(&continuation);
1936 // When we arrive here, the stack top is the resume mode and 1936 // When we arrive here, the stack top is the resume mode and
1937 // result_register() holds the input value (the argument given to the 1937 // result_register() holds the input value (the argument given to the
1938 // respective resume operation). 1938 // respective resume operation).
1939 __ RecordGeneratorContinuation(); 1939 __ RecordGeneratorContinuation();
1940 __ pop(a1); 1940 __ pop(a1);
1941 __ Branch(&resume, ne, a1, 1941 __ Branch(&resume, ne, a1,
1942 Operand(Smi::FromInt(JSGeneratorObject::RETURN))); 1942 Operand(Smi::FromInt(JSGeneratorObject::RETURN)));
1943 __ push(result_register()); 1943 __ push(result_register());
1944 EmitCreateIteratorResult(true); 1944 EmitCreateIteratorResult(true);
1945 EmitUnwindBeforeReturn(); 1945 EmitUnwindAndReturn();
1946 EmitReturnSequence();
1947 1946
1948 __ bind(&suspend); 1947 __ bind(&suspend);
1949 VisitForAccumulatorValue(expr->generator_object()); 1948 VisitForAccumulatorValue(expr->generator_object());
1950 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos())); 1949 DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
1951 __ li(a1, Operand(Smi::FromInt(continuation.pos()))); 1950 __ li(a1, Operand(Smi::FromInt(continuation.pos())));
1952 __ sw(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset)); 1951 __ sw(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset));
1953 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset)); 1952 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset));
1954 __ mov(a1, cp); 1953 __ mov(a1, cp);
1955 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2, 1954 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2,
1956 kRAHasBeenSaved, kDontSaveFPRegs); 1955 kRAHasBeenSaved, kDontSaveFPRegs);
1957 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset)); 1956 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset));
1958 __ Branch(&post_runtime, eq, sp, Operand(a1)); 1957 __ Branch(&post_runtime, eq, sp, Operand(a1));
1959 __ push(v0); // generator object 1958 __ push(v0); // generator object
1960 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 1959 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
1961 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1960 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1962 __ bind(&post_runtime); 1961 __ bind(&post_runtime);
1963 __ pop(result_register()); 1962 __ pop(result_register());
1964 EmitReturnSequence(); 1963 EmitReturnSequence();
1965 1964
1966 __ bind(&resume); 1965 __ bind(&resume);
1967 context()->Plug(result_register()); 1966 context()->Plug(result_register());
1968 break; 1967 break;
1969 } 1968 }
1970 1969
1971 case Yield::kFinal: { 1970 case Yield::kFinal: {
1972 // Pop value from top-of-stack slot, box result into result register. 1971 // Pop value from top-of-stack slot, box result into result register.
1973 EmitCreateIteratorResult(true); 1972 EmitCreateIteratorResult(true);
1974 EmitUnwindBeforeReturn(); 1973 EmitUnwindAndReturn();
1975 EmitReturnSequence();
1976 break; 1974 break;
1977 } 1975 }
1978 1976
1979 case Yield::kDelegating: { 1977 case Yield::kDelegating: {
1980 VisitForStackValue(expr->generator_object()); 1978 VisitForStackValue(expr->generator_object());
1981 1979
1982 // Initial stack layout is as follows: 1980 // Initial stack layout is as follows:
1983 // [sp + 1 * kPointerSize] iter 1981 // [sp + 1 * kPointerSize] iter
1984 // [sp + 0 * kPointerSize] g 1982 // [sp + 0 * kPointerSize] g
1985 1983
(...skipping 2671 matching lines...) Expand 10 before | Expand all | Expand 10 after
4657 } 4655 }
4658 __ push(at); 4656 __ push(at);
4659 } 4657 }
4660 4658
4661 4659
4662 // ---------------------------------------------------------------------------- 4660 // ----------------------------------------------------------------------------
4663 // Non-local control flow support. 4661 // Non-local control flow support.
4664 4662
4665 void FullCodeGenerator::EnterFinallyBlock() { 4663 void FullCodeGenerator::EnterFinallyBlock() {
4666 DCHECK(!result_register().is(a1)); 4664 DCHECK(!result_register().is(a1));
4667 // Store result register while executing finally block.
4668 __ push(result_register());
4669 // Cook return address in link register to stack (smi encoded Code* delta).
4670 __ Subu(a1, ra, Operand(masm_->CodeObject()));
4671 DCHECK_EQ(1, kSmiTagSize + kSmiShiftSize);
4672 STATIC_ASSERT(0 == kSmiTag);
4673 __ Addu(a1, a1, Operand(a1)); // Convert to smi.
4674
4675 // Store result register while executing finally block.
4676 __ push(a1);
4677
4678 // Store pending message while executing finally block. 4665 // Store pending message while executing finally block.
4679 ExternalReference pending_message_obj = 4666 ExternalReference pending_message_obj =
4680 ExternalReference::address_of_pending_message_obj(isolate()); 4667 ExternalReference::address_of_pending_message_obj(isolate());
4681 __ li(at, Operand(pending_message_obj)); 4668 __ li(at, Operand(pending_message_obj));
4682 __ lw(a1, MemOperand(at)); 4669 __ lw(a1, MemOperand(at));
4683 __ push(a1); 4670 __ push(a1);
4684 4671
4685 ClearPendingMessage(); 4672 ClearPendingMessage();
4686 } 4673 }
4687 4674
4688 4675
4689 void FullCodeGenerator::ExitFinallyBlock() { 4676 void FullCodeGenerator::ExitFinallyBlock() {
4690 DCHECK(!result_register().is(a1)); 4677 DCHECK(!result_register().is(a1));
4691 // Restore pending message from stack. 4678 // Restore pending message from stack.
4692 __ pop(a1); 4679 __ pop(a1);
4693 ExternalReference pending_message_obj = 4680 ExternalReference pending_message_obj =
4694 ExternalReference::address_of_pending_message_obj(isolate()); 4681 ExternalReference::address_of_pending_message_obj(isolate());
4695 __ li(at, Operand(pending_message_obj)); 4682 __ li(at, Operand(pending_message_obj));
4696 __ sw(a1, MemOperand(at)); 4683 __ sw(a1, MemOperand(at));
4697
4698 // Restore result register from stack.
4699 __ pop(a1);
4700
4701 // Uncook return address and return.
4702 __ pop(result_register());
4703 DCHECK_EQ(1, kSmiTagSize + kSmiShiftSize);
4704 __ sra(a1, a1, 1); // Un-smi-tag value.
4705 __ Addu(at, a1, Operand(masm_->CodeObject()));
4706 __ Jump(at);
4707 } 4684 }
4708 4685
4709 4686
4710 void FullCodeGenerator::ClearPendingMessage() { 4687 void FullCodeGenerator::ClearPendingMessage() {
4711 DCHECK(!result_register().is(a1)); 4688 DCHECK(!result_register().is(a1));
4712 ExternalReference pending_message_obj = 4689 ExternalReference pending_message_obj =
4713 ExternalReference::address_of_pending_message_obj(isolate()); 4690 ExternalReference::address_of_pending_message_obj(isolate());
4714 __ LoadRoot(a1, Heap::kTheHoleValueRootIndex); 4691 __ LoadRoot(a1, Heap::kTheHoleValueRootIndex);
4715 __ li(at, Operand(pending_message_obj)); 4692 __ li(at, Operand(pending_message_obj));
4716 __ sw(a1, MemOperand(at)); 4693 __ sw(a1, MemOperand(at));
4717 } 4694 }
4718 4695
4719 4696
4720 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) { 4697 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorSlot slot) {
4721 DCHECK(!slot.IsInvalid()); 4698 DCHECK(!slot.IsInvalid());
4722 __ li(VectorStoreICTrampolineDescriptor::SlotRegister(), 4699 __ li(VectorStoreICTrampolineDescriptor::SlotRegister(),
4723 Operand(SmiFromSlot(slot))); 4700 Operand(SmiFromSlot(slot)));
4724 } 4701 }
4725 4702
4703 void FullCodeGenerator::DeferredCommands::EmitCommands() {
4704 DCHECK(!result_register().is(a1));
4705 __ Pop(result_register()); // Restore the accumulator.
4706 __ Pop(a1); // Get the token.
4707 for (DeferredCommand cmd : commands_) {
4708 Label skip;
4709 __ li(at, Operand(Smi::FromInt(cmd.token)));
4710 __ Branch(&skip, ne, a1, Operand(at));
4711 switch (cmd.command) {
4712 case kReturn:
4713 codegen_->EmitUnwindAndReturn();
4714 break;
4715 case kThrow:
4716 __ Push(result_register());
4717 __ CallRuntime(Runtime::kReThrow);
4718 break;
4719 case kContinue:
4720 codegen_->EmitContinue(cmd.target);
4721 break;
4722 case kBreak:
4723 codegen_->EmitBreak(cmd.target);
4724 break;
4725 }
4726 __ bind(&skip);
4727 }
4728 }
4726 4729
4727 #undef __ 4730 #undef __
4728 4731
4729 4732
4730 void BackEdgeTable::PatchAt(Code* unoptimized_code, 4733 void BackEdgeTable::PatchAt(Code* unoptimized_code,
4731 Address pc, 4734 Address pc,
4732 BackEdgeState target_state, 4735 BackEdgeState target_state,
4733 Code* replacement_code) { 4736 Code* replacement_code) {
4734 static const int kInstrSize = Assembler::kInstrSize; 4737 static const int kInstrSize = Assembler::kInstrSize;
4735 Address branch_address = pc - 6 * kInstrSize; 4738 Address branch_address = pc - 6 * kInstrSize;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
4801 reinterpret_cast<uint32_t>( 4804 reinterpret_cast<uint32_t>(
4802 isolate->builtins()->OsrAfterStackCheck()->entry())); 4805 isolate->builtins()->OsrAfterStackCheck()->entry()));
4803 return OSR_AFTER_STACK_CHECK; 4806 return OSR_AFTER_STACK_CHECK;
4804 } 4807 }
4805 4808
4806 4809
4807 } // namespace internal 4810 } // namespace internal
4808 } // namespace v8 4811 } // namespace v8
4809 4812
4810 #endif // V8_TARGET_ARCH_MIPS 4813 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/full-codegen/ia32/full-codegen-ia32.cc ('k') | src/full-codegen/mips64/full-codegen-mips64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698