OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 #ifndef V8_ARM_LITHIUM_CODEGEN_ARM_H_ | 5 #ifndef V8_PPC_LITHIUM_CODEGEN_PPC_H_ |
6 #define V8_ARM_LITHIUM_CODEGEN_ARM_H_ | 6 #define V8_PPC_LITHIUM_CODEGEN_PPC_H_ |
7 | 7 |
8 #include "src/arm/lithium-arm.h" | 8 #include "src/ppc/lithium-ppc.h" |
9 | 9 |
10 #include "src/arm/lithium-gap-resolver-arm.h" | 10 #include "src/ppc/lithium-gap-resolver-ppc.h" |
11 #include "src/deoptimizer.h" | 11 #include "src/deoptimizer.h" |
12 #include "src/lithium-codegen.h" | 12 #include "src/lithium-codegen.h" |
13 #include "src/safepoint-table.h" | 13 #include "src/safepoint-table.h" |
14 #include "src/scopes.h" | 14 #include "src/scopes.h" |
15 #include "src/utils.h" | 15 #include "src/utils.h" |
16 | 16 |
17 namespace v8 { | 17 namespace v8 { |
18 namespace internal { | 18 namespace internal { |
19 | 19 |
20 // Forward declarations. | 20 // Forward declarations. |
21 class LDeferredCode; | 21 class LDeferredCode; |
22 class SafepointGenerator; | 22 class SafepointGenerator; |
23 | 23 |
24 class LCodeGen: public LCodeGenBase { | 24 class LCodeGen : public LCodeGenBase { |
25 public: | 25 public: |
26 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) | 26 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) |
27 : LCodeGenBase(chunk, assembler, info), | 27 : LCodeGenBase(chunk, assembler, info), |
28 deoptimizations_(4, info->zone()), | 28 deoptimizations_(4, info->zone()), |
29 jump_table_(4, info->zone()), | 29 jump_table_(4, info->zone()), |
30 deoptimization_literals_(8, info->zone()), | 30 deoptimization_literals_(8, info->zone()), |
31 inlined_function_count_(0), | 31 inlined_function_count_(0), |
32 scope_(info->scope()), | 32 scope_(info->scope()), |
33 translations_(info->zone()), | 33 translations_(info->zone()), |
34 deferred_(8, info->zone()), | 34 deferred_(8, info->zone()), |
35 osr_pc_offset_(-1), | 35 osr_pc_offset_(-1), |
36 frame_is_built_(false), | 36 frame_is_built_(false), |
37 safepoints_(info->zone()), | 37 safepoints_(info->zone()), |
38 resolver_(this), | 38 resolver_(this), |
39 expected_safepoint_kind_(Safepoint::kSimple) { | 39 expected_safepoint_kind_(Safepoint::kSimple) { |
40 PopulateDeoptimizationLiteralsWithInlinedFunctions(); | 40 PopulateDeoptimizationLiteralsWithInlinedFunctions(); |
41 } | 41 } |
42 | 42 |
43 | 43 |
44 int LookupDestination(int block_id) const { | 44 int LookupDestination(int block_id) const { |
45 return chunk()->LookupDestination(block_id); | 45 return chunk()->LookupDestination(block_id); |
46 } | 46 } |
47 | 47 |
48 bool IsNextEmittedBlock(int block_id) const { | 48 bool IsNextEmittedBlock(int block_id) const { |
49 return LookupDestination(block_id) == GetNextEmittedBlock(); | 49 return LookupDestination(block_id) == GetNextEmittedBlock(); |
50 } | 50 } |
51 | 51 |
52 bool NeedsEagerFrame() const { | 52 bool NeedsEagerFrame() const { |
53 return GetStackSlotCount() > 0 || | 53 return GetStackSlotCount() > 0 || info()->is_non_deferred_calling() || |
54 info()->is_non_deferred_calling() || | 54 !info()->IsStub() || info()->requires_frame(); |
55 !info()->IsStub() || | |
56 info()->requires_frame(); | |
57 } | 55 } |
58 bool NeedsDeferredFrame() const { | 56 bool NeedsDeferredFrame() const { |
59 return !NeedsEagerFrame() && info()->is_deferred_calling(); | 57 return !NeedsEagerFrame() && info()->is_deferred_calling(); |
60 } | 58 } |
61 | 59 |
62 LinkRegisterStatus GetLinkRegisterState() const { | 60 LinkRegisterStatus GetLinkRegisterState() const { |
63 return frame_is_built_ ? kLRHasBeenSaved : kLRHasNotBeenSaved; | 61 return frame_is_built_ ? kLRHasBeenSaved : kLRHasNotBeenSaved; |
64 } | 62 } |
65 | 63 |
66 // Support for converting LOperands to assembler types. | 64 // Support for converting LOperands to assembler types. |
67 // LOperand must be a register. | 65 // LOperand must be a register. |
68 Register ToRegister(LOperand* op) const; | 66 Register ToRegister(LOperand* op) const; |
69 | 67 |
70 // LOperand is loaded into scratch, unless already a register. | 68 // LOperand is loaded into scratch, unless already a register. |
71 Register EmitLoadRegister(LOperand* op, Register scratch); | 69 Register EmitLoadRegister(LOperand* op, Register scratch); |
72 | 70 |
| 71 // LConstantOperand must be an Integer32 or Smi |
| 72 void EmitLoadIntegerConstant(LConstantOperand* const_op, Register dst); |
| 73 |
73 // LOperand must be a double register. | 74 // LOperand must be a double register. |
74 DwVfpRegister ToDoubleRegister(LOperand* op) const; | 75 DoubleRegister ToDoubleRegister(LOperand* op) const; |
75 | 76 |
76 // LOperand is loaded into dbl_scratch, unless already a double register. | 77 intptr_t ToRepresentation(LConstantOperand* op, |
77 DwVfpRegister EmitLoadDoubleRegister(LOperand* op, | 78 const Representation& r) const; |
78 SwVfpRegister flt_scratch, | |
79 DwVfpRegister dbl_scratch); | |
80 int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const; | |
81 int32_t ToInteger32(LConstantOperand* op) const; | 79 int32_t ToInteger32(LConstantOperand* op) const; |
82 Smi* ToSmi(LConstantOperand* op) const; | 80 Smi* ToSmi(LConstantOperand* op) const; |
83 double ToDouble(LConstantOperand* op) const; | 81 double ToDouble(LConstantOperand* op) const; |
84 Operand ToOperand(LOperand* op); | 82 Operand ToOperand(LOperand* op); |
85 MemOperand ToMemOperand(LOperand* op) const; | 83 MemOperand ToMemOperand(LOperand* op) const; |
86 // Returns a MemOperand pointing to the high word of a DoubleStackSlot. | 84 // Returns a MemOperand pointing to the high word of a DoubleStackSlot. |
87 MemOperand ToHighMemOperand(LOperand* op) const; | 85 MemOperand ToHighMemOperand(LOperand* op) const; |
88 | 86 |
89 bool IsInteger32(LConstantOperand* op) const; | 87 bool IsInteger32(LConstantOperand* op) const; |
90 bool IsSmi(LConstantOperand* op) const; | 88 bool IsSmi(LConstantOperand* op) const; |
91 Handle<Object> ToHandle(LConstantOperand* op) const; | 89 Handle<Object> ToHandle(LConstantOperand* op) const; |
92 | 90 |
93 // Try to generate code for the entire chunk, but it may fail if the | 91 // Try to generate code for the entire chunk, but it may fail if the |
94 // chunk contains constructs we cannot handle. Returns true if the | 92 // chunk contains constructs we cannot handle. Returns true if the |
95 // code generation attempt succeeded. | 93 // code generation attempt succeeded. |
96 bool GenerateCode(); | 94 bool GenerateCode(); |
97 | 95 |
98 // Finish the code by setting stack height, safepoint, and bailout | 96 // Finish the code by setting stack height, safepoint, and bailout |
99 // information on it. | 97 // information on it. |
100 void FinishCode(Handle<Code> code); | 98 void FinishCode(Handle<Code> code); |
101 | 99 |
102 // Deferred code support. | 100 // Deferred code support. |
103 void DoDeferredNumberTagD(LNumberTagD* instr); | 101 void DoDeferredNumberTagD(LNumberTagD* instr); |
104 | 102 |
105 enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 }; | 103 enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 }; |
106 void DoDeferredNumberTagIU(LInstruction* instr, | 104 void DoDeferredNumberTagIU(LInstruction* instr, LOperand* value, |
107 LOperand* value, | 105 LOperand* temp1, LOperand* temp2, |
108 LOperand* temp1, | |
109 LOperand* temp2, | |
110 IntegerSignedness signedness); | 106 IntegerSignedness signedness); |
111 | 107 |
112 void DoDeferredTaggedToI(LTaggedToI* instr); | 108 void DoDeferredTaggedToI(LTaggedToI* instr); |
113 void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr); | 109 void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr); |
114 void DoDeferredStackCheck(LStackCheck* instr); | 110 void DoDeferredStackCheck(LStackCheck* instr); |
115 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr); | 111 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr); |
116 void DoDeferredStringCharFromCode(LStringCharFromCode* instr); | 112 void DoDeferredStringCharFromCode(LStringCharFromCode* instr); |
117 void DoDeferredAllocate(LAllocate* instr); | 113 void DoDeferredAllocate(LAllocate* instr); |
118 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, | 114 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, |
119 Label* map_check, Label* bool_load); | 115 Label* map_check); |
120 void DoDeferredInstanceMigration(LCheckMaps* instr, Register object); | 116 void DoDeferredInstanceMigration(LCheckMaps* instr, Register object); |
121 void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, | 117 void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, Register result, |
122 Register result, | 118 Register object, Register index); |
123 Register object, | |
124 Register index); | |
125 | 119 |
126 // Parallel move support. | 120 // Parallel move support. |
127 void DoParallelMove(LParallelMove* move); | 121 void DoParallelMove(LParallelMove* move); |
128 void DoGap(LGap* instr); | 122 void DoGap(LGap* instr); |
129 | 123 |
130 MemOperand PrepareKeyedOperand(Register key, | 124 MemOperand PrepareKeyedOperand(Register key, Register base, |
131 Register base, | 125 bool key_is_constant, bool key_is_tagged, |
132 bool key_is_constant, | 126 int constant_key, int element_size_shift, |
133 int constant_key, | |
134 int element_size, | |
135 int shift_size, | |
136 int base_offset); | 127 int base_offset); |
137 | 128 |
138 // Emit frame translation commands for an environment. | 129 // Emit frame translation commands for an environment. |
139 void WriteTranslation(LEnvironment* environment, Translation* translation); | 130 void WriteTranslation(LEnvironment* environment, Translation* translation); |
140 | 131 |
141 // Declare methods that deal with the individual node types. | 132 // Declare methods that deal with the individual node types. |
142 #define DECLARE_DO(type) void Do##type(L##type* node); | 133 #define DECLARE_DO(type) void Do##type(L##type* node); |
143 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) | 134 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) |
144 #undef DECLARE_DO | 135 #undef DECLARE_DO |
145 | 136 |
146 private: | 137 private: |
147 StrictMode strict_mode() const { return info()->strict_mode(); } | 138 StrictMode strict_mode() const { return info()->strict_mode(); } |
148 | 139 |
149 Scope* scope() const { return scope_; } | 140 Scope* scope() const { return scope_; } |
150 | 141 |
151 Register scratch0() { return r9; } | 142 Register scratch0() { return r11; } |
152 LowDwVfpRegister double_scratch0() { return kScratchDoubleReg; } | 143 DoubleRegister double_scratch0() { return kScratchDoubleReg; } |
153 | 144 |
154 LInstruction* GetNextInstruction(); | 145 LInstruction* GetNextInstruction(); |
155 | 146 |
156 void EmitClassOfTest(Label* if_true, | 147 void EmitClassOfTest(Label* if_true, Label* if_false, |
157 Label* if_false, | 148 Handle<String> class_name, Register input, |
158 Handle<String> class_name, | 149 Register temporary, Register temporary2); |
159 Register input, | |
160 Register temporary, | |
161 Register temporary2); | |
162 | 150 |
163 int GetStackSlotCount() const { return chunk()->spill_slot_count(); } | 151 int GetStackSlotCount() const { return chunk()->spill_slot_count(); } |
164 | 152 |
165 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } | 153 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } |
166 | 154 |
167 void SaveCallerDoubles(); | 155 void SaveCallerDoubles(); |
168 void RestoreCallerDoubles(); | 156 void RestoreCallerDoubles(); |
169 | 157 |
170 // Code generation passes. Returns true if code generation should | 158 // Code generation passes. Returns true if code generation should |
171 // continue. | 159 // continue. |
172 void GenerateBodyInstructionPre(LInstruction* instr) OVERRIDE; | 160 void GenerateBodyInstructionPre(LInstruction* instr) OVERRIDE; |
173 bool GeneratePrologue(); | 161 bool GeneratePrologue(); |
174 bool GenerateDeferredCode(); | 162 bool GenerateDeferredCode(); |
175 bool GenerateJumpTable(); | 163 bool GenerateJumpTable(); |
176 bool GenerateSafepointTable(); | 164 bool GenerateSafepointTable(); |
177 | 165 |
178 // Generates the custom OSR entrypoint and sets the osr_pc_offset. | 166 // Generates the custom OSR entrypoint and sets the osr_pc_offset. |
179 void GenerateOsrPrologue(); | 167 void GenerateOsrPrologue(); |
180 | 168 |
181 enum SafepointMode { | 169 enum SafepointMode { |
182 RECORD_SIMPLE_SAFEPOINT, | 170 RECORD_SIMPLE_SAFEPOINT, |
183 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS | 171 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS |
184 }; | 172 }; |
185 | 173 |
186 int CallCodeSize(Handle<Code> code, RelocInfo::Mode mode); | 174 void CallCode(Handle<Code> code, RelocInfo::Mode mode, LInstruction* instr); |
187 | 175 |
188 void CallCode( | 176 void CallCodeGeneric(Handle<Code> code, RelocInfo::Mode mode, |
189 Handle<Code> code, | 177 LInstruction* instr, SafepointMode safepoint_mode); |
190 RelocInfo::Mode mode, | |
191 LInstruction* instr, | |
192 TargetAddressStorageMode storage_mode = CAN_INLINE_TARGET_ADDRESS); | |
193 | 178 |
194 void CallCodeGeneric( | 179 void CallRuntime(const Runtime::Function* function, int num_arguments, |
195 Handle<Code> code, | |
196 RelocInfo::Mode mode, | |
197 LInstruction* instr, | |
198 SafepointMode safepoint_mode, | |
199 TargetAddressStorageMode storage_mode = CAN_INLINE_TARGET_ADDRESS); | |
200 | |
201 void CallRuntime(const Runtime::Function* function, | |
202 int num_arguments, | |
203 LInstruction* instr, | 180 LInstruction* instr, |
204 SaveFPRegsMode save_doubles = kDontSaveFPRegs); | 181 SaveFPRegsMode save_doubles = kDontSaveFPRegs); |
205 | 182 |
206 void CallRuntime(Runtime::FunctionId id, | 183 void CallRuntime(Runtime::FunctionId id, int num_arguments, |
207 int num_arguments, | |
208 LInstruction* instr) { | 184 LInstruction* instr) { |
209 const Runtime::Function* function = Runtime::FunctionForId(id); | 185 const Runtime::Function* function = Runtime::FunctionForId(id); |
210 CallRuntime(function, num_arguments, instr); | 186 CallRuntime(function, num_arguments, instr); |
211 } | 187 } |
212 | 188 |
213 void LoadContextFromDeferred(LOperand* context); | 189 void LoadContextFromDeferred(LOperand* context); |
214 void CallRuntimeFromDeferred(Runtime::FunctionId id, | 190 void CallRuntimeFromDeferred(Runtime::FunctionId id, int argc, |
215 int argc, | 191 LInstruction* instr, LOperand* context); |
216 LInstruction* instr, | |
217 LOperand* context); | |
218 | 192 |
219 enum R1State { | 193 enum R4State { R4_UNINITIALIZED, R4_CONTAINS_TARGET }; |
220 R1_UNINITIALIZED, | |
221 R1_CONTAINS_TARGET | |
222 }; | |
223 | 194 |
224 // Generate a direct call to a known function. Expects the function | 195 // Generate a direct call to a known function. Expects the function |
225 // to be in r1. | 196 // to be in r4. |
226 void CallKnownFunction(Handle<JSFunction> function, | 197 void CallKnownFunction(Handle<JSFunction> function, |
227 int formal_parameter_count, | 198 int formal_parameter_count, int arity, |
228 int arity, | 199 LInstruction* instr, R4State r4_state); |
229 LInstruction* instr, | |
230 R1State r1_state); | |
231 | 200 |
232 void RecordSafepointWithLazyDeopt(LInstruction* instr, | 201 void RecordSafepointWithLazyDeopt(LInstruction* instr, |
233 SafepointMode safepoint_mode); | 202 SafepointMode safepoint_mode); |
234 | 203 |
235 void RegisterEnvironmentForDeoptimization(LEnvironment* environment, | 204 void RegisterEnvironmentForDeoptimization(LEnvironment* environment, |
236 Safepoint::DeoptMode mode); | 205 Safepoint::DeoptMode mode); |
237 void DeoptimizeIf(Condition condition, LInstruction* instr, | 206 void DeoptimizeIf(Condition condition, LInstruction* instr, |
238 const char* detail, Deoptimizer::BailoutType bailout_type); | 207 const char* detail, Deoptimizer::BailoutType bailout_type, |
| 208 CRegister cr = cr7); |
239 void DeoptimizeIf(Condition condition, LInstruction* instr, | 209 void DeoptimizeIf(Condition condition, LInstruction* instr, |
240 const char* detail); | 210 const char* detail, CRegister cr = cr7); |
241 | 211 |
242 void AddToTranslation(LEnvironment* environment, | 212 void AddToTranslation(LEnvironment* environment, Translation* translation, |
243 Translation* translation, | 213 LOperand* op, bool is_tagged, bool is_uint32, |
244 LOperand* op, | |
245 bool is_tagged, | |
246 bool is_uint32, | |
247 int* object_index_pointer, | 214 int* object_index_pointer, |
248 int* dematerialized_index_pointer); | 215 int* dematerialized_index_pointer); |
249 void PopulateDeoptimizationData(Handle<Code> code); | 216 void PopulateDeoptimizationData(Handle<Code> code); |
250 int DefineDeoptimizationLiteral(Handle<Object> literal); | 217 int DefineDeoptimizationLiteral(Handle<Object> literal); |
251 | 218 |
252 void PopulateDeoptimizationLiteralsWithInlinedFunctions(); | 219 void PopulateDeoptimizationLiteralsWithInlinedFunctions(); |
253 | 220 |
254 Register ToRegister(int index) const; | 221 Register ToRegister(int index) const; |
255 DwVfpRegister ToDoubleRegister(int index) const; | 222 DoubleRegister ToDoubleRegister(int index) const; |
256 | 223 |
257 MemOperand BuildSeqStringOperand(Register string, | 224 MemOperand BuildSeqStringOperand(Register string, LOperand* index, |
258 LOperand* index, | |
259 String::Encoding encoding); | 225 String::Encoding encoding); |
260 | 226 |
261 void EmitIntegerMathAbs(LMathAbs* instr); | 227 void EmitMathAbs(LMathAbs* instr); |
| 228 #if V8_TARGET_ARCH_PPC64 |
| 229 void EmitInteger32MathAbs(LMathAbs* instr); |
| 230 #endif |
262 | 231 |
263 // Support for recording safepoint and position information. | 232 // Support for recording safepoint and position information. |
264 void RecordSafepoint(LPointerMap* pointers, | 233 void RecordSafepoint(LPointerMap* pointers, Safepoint::Kind kind, |
265 Safepoint::Kind kind, | 234 int arguments, Safepoint::DeoptMode mode); |
266 int arguments, | |
267 Safepoint::DeoptMode mode); | |
268 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode); | 235 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode); |
269 void RecordSafepoint(Safepoint::DeoptMode mode); | 236 void RecordSafepoint(Safepoint::DeoptMode mode); |
270 void RecordSafepointWithRegisters(LPointerMap* pointers, | 237 void RecordSafepointWithRegisters(LPointerMap* pointers, int arguments, |
271 int arguments, | |
272 Safepoint::DeoptMode mode); | 238 Safepoint::DeoptMode mode); |
273 | 239 |
274 void RecordAndWritePosition(int position) OVERRIDE; | 240 void RecordAndWritePosition(int position) OVERRIDE; |
275 | 241 |
276 static Condition TokenToCondition(Token::Value op, bool is_unsigned); | 242 static Condition TokenToCondition(Token::Value op); |
277 void EmitGoto(int block); | 243 void EmitGoto(int block); |
278 | 244 |
279 // EmitBranch expects to be the last instruction of a block. | 245 // EmitBranch expects to be the last instruction of a block. |
280 template<class InstrType> | 246 template <class InstrType> |
281 void EmitBranch(InstrType instr, Condition condition); | 247 void EmitBranch(InstrType instr, Condition condition, CRegister cr = cr7); |
282 template<class InstrType> | 248 template <class InstrType> |
283 void EmitFalseBranch(InstrType instr, Condition condition); | 249 void EmitFalseBranch(InstrType instr, Condition condition, |
| 250 CRegister cr = cr7); |
284 void EmitNumberUntagD(LNumberUntagD* instr, Register input, | 251 void EmitNumberUntagD(LNumberUntagD* instr, Register input, |
285 DwVfpRegister result, NumberUntagDMode mode); | 252 DoubleRegister result, NumberUntagDMode mode); |
286 | 253 |
287 // Emits optimized code for typeof x == "y". Modifies input register. | 254 // Emits optimized code for typeof x == "y". Modifies input register. |
288 // Returns the condition on which a final split to | 255 // Returns the condition on which a final split to |
289 // true and false label should be made, to optimize fallthrough. | 256 // true and false label should be made, to optimize fallthrough. |
290 Condition EmitTypeofIs(Label* true_label, | 257 Condition EmitTypeofIs(Label* true_label, Label* false_label, Register input, |
291 Label* false_label, | |
292 Register input, | |
293 Handle<String> type_name); | 258 Handle<String> type_name); |
294 | 259 |
295 // Emits optimized code for %_IsObject(x). Preserves input register. | 260 // Emits optimized code for %_IsObject(x). Preserves input register. |
296 // Returns the condition on which a final split to | 261 // Returns the condition on which a final split to |
297 // true and false label should be made, to optimize fallthrough. | 262 // true and false label should be made, to optimize fallthrough. |
298 Condition EmitIsObject(Register input, | 263 Condition EmitIsObject(Register input, Register temp1, Label* is_not_object, |
299 Register temp1, | |
300 Label* is_not_object, | |
301 Label* is_object); | 264 Label* is_object); |
302 | 265 |
303 // Emits optimized code for %_IsString(x). Preserves input register. | 266 // Emits optimized code for %_IsString(x). Preserves input register. |
304 // Returns the condition on which a final split to | 267 // Returns the condition on which a final split to |
305 // true and false label should be made, to optimize fallthrough. | 268 // true and false label should be made, to optimize fallthrough. |
306 Condition EmitIsString(Register input, | 269 Condition EmitIsString(Register input, Register temp1, Label* is_not_string, |
307 Register temp1, | |
308 Label* is_not_string, | |
309 SmiCheck check_needed); | 270 SmiCheck check_needed); |
310 | 271 |
311 // Emits optimized code for %_IsConstructCall(). | 272 // Emits optimized code for %_IsConstructCall(). |
312 // Caller should branch on equal condition. | 273 // Caller should branch on equal condition. |
313 void EmitIsConstructCall(Register temp1, Register temp2); | 274 void EmitIsConstructCall(Register temp1, Register temp2); |
314 | 275 |
315 // Emits optimized code to deep-copy the contents of statically known | 276 // Emits optimized code to deep-copy the contents of statically known |
316 // object graphs (e.g. object literal boilerplate). | 277 // object graphs (e.g. object literal boilerplate). |
317 void EmitDeepCopy(Handle<JSObject> object, | 278 void EmitDeepCopy(Handle<JSObject> object, Register result, Register source, |
318 Register result, | 279 int* offset, AllocationSiteMode mode); |
319 Register source, | |
320 int* offset, | |
321 AllocationSiteMode mode); | |
322 | 280 |
323 void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE; | 281 void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE; |
324 void DoLoadKeyedExternalArray(LLoadKeyed* instr); | 282 void DoLoadKeyedExternalArray(LLoadKeyed* instr); |
325 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr); | 283 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr); |
326 void DoLoadKeyedFixedArray(LLoadKeyed* instr); | 284 void DoLoadKeyedFixedArray(LLoadKeyed* instr); |
327 void DoStoreKeyedExternalArray(LStoreKeyed* instr); | 285 void DoStoreKeyedExternalArray(LStoreKeyed* instr); |
328 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr); | 286 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr); |
329 void DoStoreKeyedFixedArray(LStoreKeyed* instr); | 287 void DoStoreKeyedFixedArray(LStoreKeyed* instr); |
330 | 288 |
331 template <class T> | 289 template <class T> |
(...skipping 18 matching lines...) Expand all Loading... |
350 | 308 |
351 Safepoint::Kind expected_safepoint_kind_; | 309 Safepoint::Kind expected_safepoint_kind_; |
352 | 310 |
353 class PushSafepointRegistersScope FINAL BASE_EMBEDDED { | 311 class PushSafepointRegistersScope FINAL BASE_EMBEDDED { |
354 public: | 312 public: |
355 explicit PushSafepointRegistersScope(LCodeGen* codegen) | 313 explicit PushSafepointRegistersScope(LCodeGen* codegen) |
356 : codegen_(codegen) { | 314 : codegen_(codegen) { |
357 DCHECK(codegen_->info()->is_calling()); | 315 DCHECK(codegen_->info()->is_calling()); |
358 DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple); | 316 DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple); |
359 codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters; | 317 codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters; |
360 codegen_->masm_->PushSafepointRegisters(); | 318 StoreRegistersStateStub stub(codegen_->isolate()); |
| 319 codegen_->masm_->CallStub(&stub); |
361 } | 320 } |
362 | 321 |
363 ~PushSafepointRegistersScope() { | 322 ~PushSafepointRegistersScope() { |
364 DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters); | 323 DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters); |
365 codegen_->masm_->PopSafepointRegisters(); | 324 RestoreRegistersStateStub stub(codegen_->isolate()); |
| 325 codegen_->masm_->CallStub(&stub); |
366 codegen_->expected_safepoint_kind_ = Safepoint::kSimple; | 326 codegen_->expected_safepoint_kind_ = Safepoint::kSimple; |
367 } | 327 } |
368 | 328 |
369 private: | 329 private: |
370 LCodeGen* codegen_; | 330 LCodeGen* codegen_; |
371 }; | 331 }; |
372 | 332 |
373 friend class LDeferredCode; | 333 friend class LDeferredCode; |
374 friend class LEnvironment; | 334 friend class LEnvironment; |
375 friend class SafepointGenerator; | 335 friend class SafepointGenerator; |
(...skipping 23 matching lines...) Expand all Loading... |
399 LCodeGen* codegen() const { return codegen_; } | 359 LCodeGen* codegen() const { return codegen_; } |
400 MacroAssembler* masm() const { return codegen_->masm(); } | 360 MacroAssembler* masm() const { return codegen_->masm(); } |
401 | 361 |
402 private: | 362 private: |
403 LCodeGen* codegen_; | 363 LCodeGen* codegen_; |
404 Label entry_; | 364 Label entry_; |
405 Label exit_; | 365 Label exit_; |
406 Label* external_exit_; | 366 Label* external_exit_; |
407 int instruction_index_; | 367 int instruction_index_; |
408 }; | 368 }; |
| 369 } |
| 370 } // namespace v8::internal |
409 | 371 |
410 } } // namespace v8::internal | 372 #endif // V8_PPC_LITHIUM_CODEGEN_PPC_H_ |
411 | |
412 #endif // V8_ARM_LITHIUM_CODEGEN_ARM_H_ | |
OLD | NEW |