OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
6 #if defined(TARGET_ARCH_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
7 | 7 |
8 #include "vm/flow_graph_compiler.h" | 8 #include "vm/flow_graph_compiler.h" |
9 | 9 |
10 #include "lib/error.h" | 10 #include "lib/error.h" |
11 #include "vm/ast_printer.h" | 11 #include "vm/ast_printer.h" |
12 #include "vm/dart_entry.h" | 12 #include "vm/dart_entry.h" |
13 #include "vm/deopt_instructions.h" | |
13 #include "vm/il_printer.h" | 14 #include "vm/il_printer.h" |
14 #include "vm/locations.h" | 15 #include "vm/locations.h" |
15 #include "vm/object_store.h" | 16 #include "vm/object_store.h" |
16 #include "vm/parser.h" | 17 #include "vm/parser.h" |
17 #include "vm/stack_frame.h" | 18 #include "vm/stack_frame.h" |
18 #include "vm/stub_code.h" | 19 #include "vm/stub_code.h" |
19 #include "vm/symbols.h" | 20 #include "vm/symbols.h" |
20 | 21 |
21 namespace dart { | 22 namespace dart { |
22 | 23 |
(...skipping 12 matching lines...) Expand all Loading... | |
35 ASSERT(!block_info_[i]->jump_label()->IsLinked()); | 36 ASSERT(!block_info_[i]->jump_label()->IsLinked()); |
36 } | 37 } |
37 } | 38 } |
38 | 39 |
39 | 40 |
40 bool FlowGraphCompiler::SupportsUnboxedMints() { | 41 bool FlowGraphCompiler::SupportsUnboxedMints() { |
41 return false; | 42 return false; |
42 } | 43 } |
43 | 44 |
44 | 45 |
46 RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, | |
47 DeoptInfoBuilder* builder) { | |
48 if (deoptimization_env_ == NULL) return DeoptInfo::null(); | |
49 | |
50 intptr_t stack_height = compiler->StackSize(); | |
51 AllocateIncomingParametersRecursive(deoptimization_env_, &stack_height); | |
52 | |
53 intptr_t slot_ix = 0; | |
54 Environment* current = deoptimization_env_; | |
55 | |
56 // Emit all kMaterializeObject instructions describing objects to be | |
57 // materialized on the deoptimization as a prefix to the deoptimization info. | |
58 EmitMaterializations(deoptimization_env_, builder); | |
59 | |
60 // The real frame starts here. | |
61 builder->MarkFrameStart(); | |
62 | |
63 // Current PP, FP, and PC. | |
64 builder->AddPp(current->function(), slot_ix++); | |
65 builder->AddCallerFp(slot_ix++); | |
66 builder->AddReturnAddress(current->function(), | |
67 deopt_id(), | |
68 slot_ix++); | |
69 | |
70 // Callee's PC marker is not used anymore. Pass Function::null() to set to 0. | |
71 builder->AddPcMarker(Function::Handle(), slot_ix++); | |
72 | |
73 // Emit all values that are needed for materialization as a part of the | |
74 // expression stack for the bottom-most frame. This guarantees that GC | |
75 // will be able to find them during materialization. | |
76 slot_ix = builder->EmitMaterializationArguments(slot_ix); | |
77 | |
78 // For the innermost environment, set outgoing arguments and the locals. | |
79 for (intptr_t i = current->Length() - 1; | |
80 i >= current->fixed_parameter_count(); | |
81 i--) { | |
82 builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++); | |
83 } | |
84 | |
85 Environment* previous = current; | |
86 current = current->outer(); | |
87 while (current != NULL) { | |
88 // PP, FP, and PC. | |
89 builder->AddPp(current->function(), slot_ix++); | |
90 builder->AddCallerFp(slot_ix++); | |
91 | |
92 // For any outer environment the deopt id is that of the call instruction | |
93 // which is recorded in the outer environment. | |
94 builder->AddReturnAddress(current->function(), | |
95 Isolate::ToDeoptAfter(current->deopt_id()), | |
96 slot_ix++); | |
97 | |
98 // PC marker. | |
99 builder->AddPcMarker(previous->function(), slot_ix++); | |
100 | |
101 // The values of outgoing arguments can be changed from the inlined call so | |
102 // we must read them from the previous environment. | |
103 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { | |
104 builder->AddCopy(previous->ValueAt(i), | |
105 previous->LocationAt(i), | |
106 slot_ix++); | |
107 } | |
108 | |
109 // Set the locals, note that outgoing arguments are not in the environment. | |
110 for (intptr_t i = current->Length() - 1; | |
111 i >= current->fixed_parameter_count(); | |
112 i--) { | |
113 builder->AddCopy(current->ValueAt(i), | |
114 current->LocationAt(i), | |
115 slot_ix++); | |
116 } | |
117 | |
118 // Iterate on the outer environment. | |
119 previous = current; | |
120 current = current->outer(); | |
121 } | |
122 // The previous pointer is now the outermost environment. | |
123 ASSERT(previous != NULL); | |
124 | |
125 // For the outermost environment, set caller PC, caller PP, and caller FP. | |
126 builder->AddCallerPp(slot_ix++); | |
127 builder->AddCallerFp(slot_ix++); | |
128 builder->AddCallerPc(slot_ix++); | |
129 | |
130 // PC marker. | |
131 builder->AddPcMarker(previous->function(), slot_ix++); | |
132 | |
133 // For the outermost environment, set the incoming arguments. | |
134 for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { | |
135 builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++); | |
136 } | |
137 | |
138 const DeoptInfo& deopt_info = DeoptInfo::Handle(builder->CreateDeoptInfo()); | |
139 return deopt_info.raw(); | |
140 } | |
141 | |
142 | |
45 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler, | 143 void CompilerDeoptInfoWithStub::GenerateCode(FlowGraphCompiler* compiler, |
46 intptr_t stub_ix) { | 144 intptr_t stub_ix) { |
47 // Calls do not need stubs, they share a deoptimization trampoline. | 145 // Calls do not need stubs, they share a deoptimization trampoline. |
48 ASSERT(reason() != kDeoptAtCall); | 146 ASSERT(reason() != kDeoptAtCall); |
49 Assembler* assem = compiler->assembler(); | 147 Assembler* assem = compiler->assembler(); |
50 #define __ assem-> | 148 #define __ assem-> |
51 __ Comment("Deopt stub for id %"Pd"", deopt_id()); | 149 __ Comment("Deopt stub for id %"Pd"", deopt_id()); |
52 __ Bind(entry_label()); | 150 __ Bind(entry_label()); |
53 if (FLAG_trap_on_deoptimization) __ bkpt(0); | 151 if (FLAG_trap_on_deoptimization) __ bkpt(0); |
54 | 152 |
55 ASSERT(deoptimization_env() != NULL); | 153 ASSERT(deoptimization_env() != NULL); |
56 | 154 |
57 __ BranchLink(&StubCode::DeoptimizeLabel()); | 155 __ BranchLink(&StubCode::DeoptimizeLabel()); |
58 set_pc_offset(assem->CodeSize()); | 156 set_pc_offset(assem->CodeSize()); |
zra
2013/05/14 22:28:56
On ia32 and x64, there is a breakpoint here. Shoul
regis
2013/05/14 23:23:42
It is safer to have one, but it takes up space. I
| |
59 #undef __ | 157 #undef __ |
60 } | 158 } |
61 | 159 |
62 | 160 |
63 #define __ assembler()-> | 161 #define __ assembler()-> |
64 | 162 |
65 | 163 |
66 // Fall through if bool_register contains null. | 164 // Fall through if bool_register contains null. |
67 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register, | 165 void FlowGraphCompiler::GenerateBoolToJump(Register bool_register, |
68 Label* is_true, | 166 Label* is_true, |
(...skipping 1407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1476 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { | 1574 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { |
1477 __ vldrd(reg, Address(SP, kDoubleSize, Address::PostIndex)); | 1575 __ vldrd(reg, Address(SP, kDoubleSize, Address::PostIndex)); |
1478 } | 1576 } |
1479 | 1577 |
1480 | 1578 |
1481 #undef __ | 1579 #undef __ |
1482 | 1580 |
1483 } // namespace dart | 1581 } // namespace dart |
1484 | 1582 |
1485 #endif // defined TARGET_ARCH_ARM | 1583 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |