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

Side by Side Diff: runtime/vm/flow_graph_compiler_arm64.cc

Issue 246293010: Enables first codegen test on arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
7 7
8 #include "vm/flow_graph_compiler.h" 8 #include "vm/flow_graph_compiler.h"
9 9
10 #include "vm/ast_printer.h" 10 #include "vm/ast_printer.h"
11 #include "vm/compiler.h" 11 #include "vm/compiler.h"
12 #include "vm/cpu.h" 12 #include "vm/cpu.h"
13 #include "vm/dart_entry.h" 13 #include "vm/dart_entry.h"
14 #include "vm/deopt_instructions.h" 14 #include "vm/deopt_instructions.h"
15 #include "vm/il_printer.h" 15 #include "vm/il_printer.h"
16 #include "vm/locations.h" 16 #include "vm/locations.h"
17 #include "vm/object_store.h" 17 #include "vm/object_store.h"
18 #include "vm/parser.h" 18 #include "vm/parser.h"
19 #include "vm/stack_frame.h" 19 #include "vm/stack_frame.h"
20 #include "vm/stub_code.h" 20 #include "vm/stub_code.h"
21 #include "vm/symbols.h" 21 #include "vm/symbols.h"
22 22
23 namespace dart { 23 namespace dart {
24 24
25 DECLARE_FLAG(int, optimization_counter_threshold);
26 DECLARE_FLAG(int, reoptimization_counter_threshold);
27
25 FlowGraphCompiler::~FlowGraphCompiler() { 28 FlowGraphCompiler::~FlowGraphCompiler() {
26 // BlockInfos are zone-allocated, so their destructors are not called. 29 // BlockInfos are zone-allocated, so their destructors are not called.
27 // Verify the labels explicitly here. 30 // Verify the labels explicitly here.
28 for (int i = 0; i < block_info_.length(); ++i) { 31 for (int i = 0; i < block_info_.length(); ++i) {
29 ASSERT(!block_info_[i]->jump_label()->IsLinked()); 32 ASSERT(!block_info_[i]->jump_label()->IsLinked());
30 } 33 }
31 } 34 }
32 35
33 36
34 bool FlowGraphCompiler::SupportsUnboxedMints() { 37 bool FlowGraphCompiler::SupportsUnboxedMints() {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos, 157 void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
155 intptr_t deopt_id, 158 intptr_t deopt_id,
156 const AbstractType& dst_type, 159 const AbstractType& dst_type,
157 const String& dst_name, 160 const String& dst_name,
158 LocationSummary* locs) { 161 LocationSummary* locs) {
159 UNIMPLEMENTED(); 162 UNIMPLEMENTED();
160 } 163 }
161 164
162 165
163 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) { 166 void FlowGraphCompiler::EmitInstructionEpilogue(Instruction* instr) {
164 UNIMPLEMENTED(); 167 if (is_optimizing()) {
168 return;
169 }
170 Definition* defn = instr->AsDefinition();
171 if ((defn != NULL) && defn->is_used()) {
172 __ Push(defn->locs()->out(0).reg());
173 }
165 } 174 }
166 175
167 176
168 void FlowGraphCompiler::CopyParameters() { 177 void FlowGraphCompiler::CopyParameters() {
169 UNIMPLEMENTED(); 178 UNIMPLEMENTED();
170 } 179 }
171 180
172 181
173 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) { 182 void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) {
174 UNIMPLEMENTED(); 183 UNIMPLEMENTED();
175 } 184 }
176 185
177 186
178 void FlowGraphCompiler::GenerateInlinedSetter(intptr_t offset) { 187 void FlowGraphCompiler::GenerateInlinedSetter(intptr_t offset) {
179 UNIMPLEMENTED(); 188 UNIMPLEMENTED();
180 } 189 }
181 190
182 191
183 void FlowGraphCompiler::EmitFrameEntry() { 192 void FlowGraphCompiler::EmitFrameEntry() {
184 UNIMPLEMENTED(); 193 const Function& function = parsed_function().function();
194 Register new_pp = kNoRegister;
195 if (CanOptimizeFunction() &&
196 function.IsOptimizable() &&
197 (!is_optimizing() || may_reoptimize())) {
198 const Register function_reg = R6;
199 new_pp = R13;
200
201 // Set up pool pointer in new_pp.
202 __ LoadPoolPointer(new_pp);
203
204 // Load function object using the callee's pool pointer.
205 __ LoadObject(function_reg, function, new_pp);
206
207 // Patch point is after the eventually inlined function object.
208 AddCurrentDescriptor(PcDescriptors::kEntryPatch,
209 Isolate::kNoDeoptId,
210 0); // No token position.
211 intptr_t threshold = FLAG_optimization_counter_threshold;
212 __ LoadFieldFromOffset(R7, function_reg, Function::usage_counter_offset());
213 if (is_optimizing()) {
214 // Reoptimization of an optimized function is triggered by counting in
215 // IC stubs, but not at the entry of the function.
216 threshold = FLAG_reoptimization_counter_threshold;
217 } else {
218 __ add(R7, R7, Operand(1));
219 __ StoreFieldToOffset(R7, function_reg, Function::usage_counter_offset());
220 }
221 __ CompareImmediate(R7, threshold, new_pp);
222 ASSERT(function_reg == R6);
223 Label dont_optimize;
224 __ b(&dont_optimize, LT);
225 __ Branch(&StubCode::OptimizeFunctionLabel(), new_pp);
226 __ Bind(&dont_optimize);
227 } else if (!flow_graph().IsCompiledForOsr()) {
228 // We have to load the PP here too because a load of an external label
229 // may be patched at the AddCurrentDescriptor below.
230 new_pp = R13;
231
232 __ LoadPoolPointer(new_pp);
233
234 AddCurrentDescriptor(PcDescriptors::kEntryPatch,
235 Isolate::kNoDeoptId,
236 0); // No token position.
237 }
238 __ Comment("Enter frame");
239 if (flow_graph().IsCompiledForOsr()) {
240 intptr_t extra_slots = StackSize()
241 - flow_graph().num_stack_locals()
242 - flow_graph().num_copied_params();
243 ASSERT(extra_slots >= 0);
244 __ EnterOsrFrame(extra_slots * kWordSize, new_pp);
245 } else {
246 ASSERT(StackSize() >= 0);
247 __ EnterDartFrameWithInfo(StackSize() * kWordSize, new_pp);
248 }
185 } 249 }
186 250
187 251
252 // Input parameters:
253 // LR: return address.
254 // SP: address of last argument.
255 // FP: caller's frame pointer.
256 // PP: caller's pool pointer.
257 // R5: ic-data.
258 // R4: arguments descriptor array.
188 void FlowGraphCompiler::CompileGraph() { 259 void FlowGraphCompiler::CompileGraph() {
189 UNIMPLEMENTED(); 260 InitCompiler();
261
262 TryIntrinsify();
263
264 EmitFrameEntry();
265
266 const Function& function = parsed_function().function();
267
268 const int num_fixed_params = function.num_fixed_parameters();
269 const int num_copied_params = parsed_function().num_copied_params();
270 const int num_locals = parsed_function().num_stack_locals();
271
272 // We check the number of passed arguments when we have to copy them due to
273 // the presence of optional parameters.
274 // No such checking code is generated if only fixed parameters are declared,
275 // unless we are in debug mode or unless we are compiling a closure.
276 if (num_copied_params == 0) {
277 #ifdef DEBUG
278 ASSERT(!parsed_function().function().HasOptionalParameters());
279 const bool check_arguments = !flow_graph().IsCompiledForOsr();
280 #else
281 const bool check_arguments =
282 function.IsClosureFunction() && !flow_graph().IsCompiledForOsr();
283 #endif
284 if (check_arguments) {
285 __ Comment("Check argument count");
286 // Check that exactly num_fixed arguments are passed in.
287 Label correct_num_arguments, wrong_num_arguments;
288 __ LoadFieldFromOffset(R0, R4, ArgumentsDescriptor::count_offset());
289 __ CompareImmediate(R0, Smi::RawValue(num_fixed_params), PP);
290 __ b(&wrong_num_arguments, NE);
291 __ LoadFieldFromOffset(R1, R4,
292 ArgumentsDescriptor::positional_count_offset());
293 __ CompareRegisters(R0, R1);
294 __ b(&correct_num_arguments, EQ);
295 __ Bind(&wrong_num_arguments);
296 if (function.IsClosureFunction()) {
297 // Invoke noSuchMethod function passing the original function name.
298 // For closure functions, use "call" as the original name.
299 const String& name =
300 String::Handle(function.IsClosureFunction()
301 ? Symbols::Call().raw()
302 : function.name());
303 const int kNumArgsChecked = 1;
304 const ICData& ic_data = ICData::ZoneHandle(
305 ICData::New(function, name, Object::empty_array(),
306 Isolate::kNoDeoptId, kNumArgsChecked));
307 __ LoadObject(R5, ic_data, PP);
308 __ LeaveDartFrame(); // The arguments are still on the stack.
309 __ Branch(&StubCode::CallNoSuchMethodFunctionLabel(), PP);
310 // The noSuchMethod call may return to the caller, but not here.
311 __ hlt(0);
312 } else {
313 __ Stop("Wrong number of arguments");
314 }
315 __ Bind(&correct_num_arguments);
316 }
317 } else if (!flow_graph().IsCompiledForOsr()) {
318 CopyParameters();
319 }
320
321 // In unoptimized code, initialize (non-argument) stack allocated slots to
322 // null.
323 if (!is_optimizing() && (num_locals > 0)) {
324 __ Comment("Initialize spill slots");
325 const intptr_t slot_base = parsed_function().first_stack_local_index();
326 __ LoadObject(R0, Object::null_object(), PP);
327 for (intptr_t i = 0; i < num_locals; ++i) {
328 // Subtract index i (locals lie at lower addresses than FP).
329 __ StoreToOffset(R0, FP, (slot_base - i) * kWordSize);
330 }
331 }
332
333 VisitBlocks();
334
335 __ hlt(0);
336 GenerateDeferredCode();
337 // Emit function patching code. This will be swapped with the first 3
338 // instructions at entry point.
339 AddCurrentDescriptor(PcDescriptors::kPatchCode,
340 Isolate::kNoDeoptId,
341 0); // No token position.
342 // This is patched up to a point in FrameEntry where the PP for the
343 // current function is in R13 instead of PP.
344 __ BranchPatchable(&StubCode::FixCallersTargetLabel(), R13);
345
346 AddCurrentDescriptor(PcDescriptors::kLazyDeoptJump,
347 Isolate::kNoDeoptId,
348 0); // No token position.
349 // TODO(zra): Can I use a normal BranchPatchable here? Probably have to change
350 // the CodePatcher.
regis 2014/04/22 23:38:10 Sorry, I do not know or do not remember. Ask Srdja
351 __ BranchFixed(&StubCode::DeoptimizeLazyLabel());
190 } 352 }
191 353
192 354
193 void FlowGraphCompiler::GenerateCall(intptr_t token_pos, 355 void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
194 const ExternalLabel* label, 356 const ExternalLabel* label,
195 PcDescriptors::Kind kind, 357 PcDescriptors::Kind kind,
196 LocationSummary* locs) { 358 LocationSummary* locs) {
197 UNIMPLEMENTED(); 359 UNIMPLEMENTED();
198 } 360 }
199 361
200 362
201 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id, 363 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
202 intptr_t token_pos, 364 intptr_t token_pos,
203 const ExternalLabel* label, 365 const ExternalLabel* label,
204 PcDescriptors::Kind kind, 366 PcDescriptors::Kind kind,
205 LocationSummary* locs) { 367 LocationSummary* locs) {
206 UNIMPLEMENTED(); 368 UNIMPLEMENTED();
207 } 369 }
208 370
209 371
210 void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos, 372 void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos,
211 intptr_t deopt_id, 373 intptr_t deopt_id,
212 const RuntimeEntry& entry, 374 const RuntimeEntry& entry,
213 intptr_t argument_count, 375 intptr_t argument_count,
214 LocationSummary* locs) { 376 LocationSummary* locs) {
215 UNIMPLEMENTED(); 377 __ CallRuntime(entry, argument_count);
378 AddCurrentDescriptor(PcDescriptors::kOther, deopt_id, token_pos);
379 RecordSafepoint(locs);
380 if (deopt_id != Isolate::kNoDeoptId) {
381 // Marks either the continuation point in unoptimized code or the
382 // deoptimization point in optimized code, after call.
383 const intptr_t deopt_id_after = Isolate::ToDeoptAfter(deopt_id);
384 if (is_optimizing()) {
385 AddDeoptIndexAtCall(deopt_id_after, token_pos);
386 } else {
387 // Add deoptimization continuation point after the call and before the
388 // arguments are removed.
389 AddCurrentDescriptor(PcDescriptors::kDeopt, deopt_id_after, token_pos);
390 }
391 }
216 } 392 }
217 393
218 394
219 void FlowGraphCompiler::EmitEdgeCounter() { 395 void FlowGraphCompiler::EmitEdgeCounter() {
220 UNIMPLEMENTED(); 396 // We do not check for overflow when incrementing the edge counter. The
397 // function should normally be optimized long before the counter can
398 // overflow; and though we do not reset the counters when we optimize or
399 // deoptimize, there is a bound on the number of
400 // optimization/deoptimization cycles we will attempt.
401 const Array& counter = Array::ZoneHandle(Array::New(1, Heap::kOld));
402 counter.SetAt(0, Smi::Handle(Smi::New(0)));
403 __ Comment("Edge counter");
404 __ LoadObject(R0, counter, PP);
405 __ LoadFieldFromOffset(TMP, R0, Array::element_offset(0));
406 __ add(TMP, TMP, Operand(Smi::RawValue(1)));
407 __ StoreFieldToOffset(TMP, R0, Array::element_offset(0));
221 } 408 }
222 409
223 410
224 void FlowGraphCompiler::EmitOptimizedInstanceCall( 411 void FlowGraphCompiler::EmitOptimizedInstanceCall(
225 ExternalLabel* target_label, 412 ExternalLabel* target_label,
226 const ICData& ic_data, 413 const ICData& ic_data,
227 intptr_t argument_count, 414 intptr_t argument_count,
228 intptr_t deopt_id, 415 intptr_t deopt_id,
229 intptr_t token_pos, 416 intptr_t token_pos,
230 LocationSummary* locs) { 417 LocationSummary* locs) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 Register right, 473 Register right,
287 bool needs_number_check, 474 bool needs_number_check,
288 intptr_t token_pos) { 475 intptr_t token_pos) {
289 UNIMPLEMENTED(); 476 UNIMPLEMENTED();
290 } 477 }
291 478
292 479
293 // This function must be in sync with FlowGraphCompiler::RecordSafepoint and 480 // This function must be in sync with FlowGraphCompiler::RecordSafepoint and
294 // FlowGraphCompiler::SlowPathEnvironmentFor. 481 // FlowGraphCompiler::SlowPathEnvironmentFor.
295 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) { 482 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
296 UNIMPLEMENTED(); 483 // TODO(zra): Save live FPU Registers.
484
485 // Store general purpose registers with the highest register number at the
486 // lowest address.
487 for (intptr_t reg_idx = 0; reg_idx < kNumberOfCpuRegisters; ++reg_idx) {
488 Register reg = static_cast<Register>(reg_idx);
489 if (locs->live_registers()->ContainsRegister(reg)) {
490 __ Push(reg);
491 }
492 }
297 } 493 }
298 494
299 495
300 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) { 496 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
301 UNIMPLEMENTED(); 497 // General purpose registers have the highest register number at the
498 // lowest address.
499 for (intptr_t reg_idx = kNumberOfCpuRegisters - 1; reg_idx >= 0; --reg_idx) {
500 Register reg = static_cast<Register>(reg_idx);
501 if (locs->live_registers()->ContainsRegister(reg)) {
502 __ Pop(reg);
503 }
504 }
505
506 // TODO(zra): Restore live FPU registers.
302 } 507 }
303 508
304 509
305 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data, 510 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
306 Register class_id_reg, 511 Register class_id_reg,
307 intptr_t argument_count, 512 intptr_t argument_count,
308 const Array& argument_names, 513 const Array& argument_names,
309 Label* deopt, 514 Label* deopt,
310 intptr_t deopt_id, 515 intptr_t deopt_id,
311 intptr_t token_index, 516 intptr_t token_index,
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) { 625 void ParallelMoveResolver::RestoreFpuScratch(FpuRegister reg) {
421 UNIMPLEMENTED(); 626 UNIMPLEMENTED();
422 } 627 }
423 628
424 629
425 #undef __ 630 #undef __
426 631
427 } // namespace dart 632 } // namespace dart
428 633
429 #endif // defined TARGET_ARCH_ARM64 634 #endif // defined TARGET_ARCH_ARM64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698