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

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

Issue 11316353: Refactor the InstanceFunctionLookupStub. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years 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
« runtime/vm/code_generator.cc ('K') | « runtime/vm/stub_code_ia32.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/assembler_macros.h" 9 #include "vm/assembler_macros.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 __ popq(R10); // Restore arguments descriptor array. 216 __ popq(R10); // Restore arguments descriptor array.
217 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); 217 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
218 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 218 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
219 __ LeaveFrame(); 219 __ LeaveFrame();
220 __ jmp(RAX); 220 __ jmp(RAX);
221 __ int3(); 221 __ int3();
222 } 222 }
223 223
224 224
225 // Input parameters: 225 // Input parameters:
226 // R13: argument count, may be zero. 226 // R10: smi-tagged argument count, may be zero.
227 static void PushArgumentsArray(Assembler* assembler, intptr_t arg_offset) { 227 static void PushArgumentsArray(Assembler* assembler, intptr_t arg_offset) {
228 const Immediate raw_null = 228 const Immediate raw_null =
229 Immediate(reinterpret_cast<intptr_t>(Object::null())); 229 Immediate(reinterpret_cast<intptr_t>(Object::null()));
230 230
231 // Allocate array to store arguments of caller. 231 // Allocate array to store arguments of caller.
232 __ movq(R10, R13); // Arguments array length.
233 __ SmiTag(R10); // Convert to Smi.
234 __ movq(RBX, raw_null); // Null element type for raw Array. 232 __ movq(RBX, raw_null); // Null element type for raw Array.
235 __ call(&StubCode::AllocateArrayLabel()); 233 __ call(&StubCode::AllocateArrayLabel());
236 __ SmiUntag(R10); 234 __ SmiUntag(R10);
237 // RAX: newly allocated array. 235 // RAX: newly allocated array.
238 // R10: length of the array (was preserved by the stub). 236 // R10: length of the array (was preserved by the stub).
239 __ pushq(RAX); // Array is in RAX and on top of stack. 237 __ pushq(RAX); // Array is in RAX and on top of stack.
240 __ leaq(R12, Address(RSP, R10, TIMES_8, arg_offset)); // Addr of first arg. 238 __ leaq(R12, Address(RSP, R10, TIMES_8, arg_offset)); // Addr of first arg.
241 __ leaq(RBX, FieldAddress(RAX, Array::data_offset())); 239 __ leaq(RBX, FieldAddress(RAX, Array::data_offset()));
242 Label loop, loop_condition; 240 Label loop, loop_condition;
243 __ jmp(&loop_condition, Assembler::kNearJump); 241 __ jmp(&loop_condition, Assembler::kNearJump);
244 __ Bind(&loop); 242 __ Bind(&loop);
245 __ movq(RAX, Address(R12, 0)); 243 __ movq(RAX, Address(R12, 0));
246 __ movq(Address(RBX, 0), RAX); 244 __ movq(Address(RBX, 0), RAX);
247 __ AddImmediate(RBX, Immediate(kWordSize)); 245 __ AddImmediate(RBX, Immediate(kWordSize));
248 __ AddImmediate(R12, Immediate(-kWordSize)); 246 __ AddImmediate(R12, Immediate(-kWordSize));
249 __ Bind(&loop_condition); 247 __ Bind(&loop_condition);
250 __ decq(R10); 248 __ decq(R10);
251 __ j(POSITIVE, &loop, Assembler::kNearJump); 249 __ j(POSITIVE, &loop, Assembler::kNearJump);
252 } 250 }
253 251
254 252
255 // Input parameters: 253 // Input parameters:
256 // RBX: ic-data. 254 // RBX: ic-data.
257 // R10: arguments descriptor array. 255 // R10: arguments descriptor array.
258 // Note: The receiver object is the first argument to the function being 256 // Note: The receiver object is the first argument to the function being
259 // called, the stub accesses the receiver from this location directly 257 // called, the stub accesses the receiver from this location directly
260 // when trying to resolve the call. 258 // when trying to resolve the call.
261 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { 259 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) {
260 AssemblerMacros::EnterStubFrame(assembler);
261
262 const Immediate raw_null = 262 const Immediate raw_null =
263 Immediate(reinterpret_cast<intptr_t>(Object::null())); 263 Immediate(reinterpret_cast<intptr_t>(Object::null()));
264 __ pushq(raw_null); // Space for the return value.
264 265
265 // Create a stub frame as we are pushing some objects on the stack before 266 // Push the receiver as an argument. Load the smi-tagged argument
266 // calling into the runtime. 267 // count into R13 to index the receiver in the stack. There are
267 AssemblerMacros::EnterStubFrame(assembler); 268 // three words (null, stub's pc marker, saved fp) above the return
269 // address.
270 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
271 __ pushq(Address(RSP, R13, TIMES_4, (3 * kWordSize)));
268 272
269 // Preserve values across call to resolving. 273 __ pushq(RBX); // Pass IC data object.
270 // Stack at this point: 274 __ pushq(R10); // Pass arguments descriptor array.
271 // TOS + 0: PC marker => RawInstruction object.
272 // TOS + 1: Saved RBP of previous frame. <== RBP
273 // TOS + 2: Dart code return address
274 // TOS + 3: Last argument of caller.
275 // ....
276 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
277 __ movq(RAX, Address(RBP, RAX, TIMES_4, kWordSize)); // Get receiver.
278 // RAX: receiver.
279 // RBX: ic-data.
280 // R10: arguments descriptor array.
281 // The target function was not found.
282 // First check to see if this is a getter function and we are
283 // trying to create a closure of an instance function.
284 // Push values that need to be preserved across runtime call.
285 __ pushq(RAX); // Preserve receiver.
286 __ pushq(RBX); // Preserve ic-data.
287 __ pushq(R10); // Preserve arguments descriptor array.
288 275
289 __ pushq(raw_null); // Setup space on stack for return value. 276 // Pass the call's arguments array.
290 __ pushq(RAX); // Push receiver. 277 __ movq(R10, R13); // Smi-tagged arguments array length.
291 __ pushq(RBX); // Ic-data array. 278 PushArgumentsArray(assembler, (7 * kWordSize));
292 __ CallRuntime(kResolveImplicitClosureFunctionRuntimeEntry); 279 // Stack layout explaining "(7 * kWordSize)" offset.
293 __ popq(RAX);
294 __ popq(RAX);
295 __ popq(RCX); // Get return value into RCX, might be Closure object.
296
297 // Pop preserved values.
298 __ popq(R10); // Restore arguments descriptor array.
299 __ popq(RBX); // Restore ic-data.
300 __ popq(RAX); // Restore receiver.
301
302 __ cmpq(RCX, raw_null);
303 Label check_implicit_closure_through_getter;
304 __ j(EQUAL, &check_implicit_closure_through_getter, Assembler::kNearJump);
305
306 __ movq(RAX, RCX); // Return value is the closure object.
307 // Remove the stub frame as we are about return.
308 __ LeaveFrame();
309 __ ret();
310
311 __ Bind(&check_implicit_closure_through_getter);
312 // RAX: receiver.
313 // RBX: ic-data.
314 // R10: arguments descriptor array.
315 // This is not the case of an instance so invoke the getter of the
316 // same name and see if we get a closure back which we are then
317 // supposed to invoke.
318 // Push values that need to be preserved across runtime call.
319 __ pushq(RAX); // Preserve receiver.
320 __ pushq(RBX); // Preserve ic-data.
321 __ pushq(R10); // Preserve arguments descriptor array.
322
323 __ pushq(raw_null); // Setup space on stack for return value.
324 __ pushq(RAX); // Push receiver.
325 __ pushq(RBX); // Ic-data array.
326 __ CallRuntime(kResolveImplicitClosureThroughGetterRuntimeEntry);
327 __ popq(RAX); // Pop argument.
328 __ popq(RAX); // Pop argument.
329 __ popq(RCX); // get return value into RCX, might be Closure object.
330
331 // Pop preserved values.
332 __ popq(R10); // Restore arguments descriptor array.
333 __ popq(RBX); // Restore ic-data.
334 __ popq(RAX); // Restore receiver.
335
336 __ cmpq(RCX, raw_null);
337 Label function_not_found;
338 __ j(EQUAL, &function_not_found);
339
340 // RCX: Closure object.
341 // R10: Arguments descriptor array.
342 __ pushq(raw_null); // Setup space on stack for result from invoking Closure.
343 __ pushq(RCX); // Closure object.
344 __ pushq(R10); // Arguments descriptor.
345 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
346 __ SmiUntag(R13); // Arguments array length, including the original receiver.
347 PushArgumentsArray(assembler, (kWordSize * 6));
348 // Stack layout explaining "(kWordSize * 6)" offset.
349 // TOS + 0: Argument array.
350 // TOS + 1: Arguments descriptor array.
351 // TOS + 2: Closure object.
352 // TOS + 3: Place for result from closure function.
353 // TOS + 4: PC marker => RawInstruction object.
354 // TOS + 5: Saved RBP of previous frame. <== RBP
355 // TOS + 6: Dart code return address
356 // TOS + 7: Last argument of caller.
357 // ....
358
359 __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry);
360 // Remove arguments.
361 __ popq(RAX);
362 __ popq(RAX);
363 __ popq(RAX);
364 __ popq(RAX); // Get result into RAX.
365
366 // Remove the stub frame as we are about to return.
367 __ LeaveFrame();
368 __ ret();
369
370 __ Bind(&function_not_found);
371 // The target function was not found, so invoke method
372 // "dynamic noSuchMethod(InvocationMirror invocation)".
373 // RAX: receiver.
374 // RBX: ic-data.
375 // R10: arguments descriptor array.
376
377 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod.
378 __ pushq(RAX); // Receiver.
379 __ pushq(RBX); // IC-data array.
380 __ pushq(R10); // Arguments descriptor array.
381 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
382 __ SmiUntag(R13); // Arguments array length, including the original receiver.
383 // See stack layout below explaining "wordSize * 7" offset.
384 PushArgumentsArray(assembler, (kWordSize * 7));
385
386 // Stack:
387 // TOS + 0: Arguments array. 280 // TOS + 0: Arguments array.
388 // TOS + 1: Arguments descriptor array. 281 // TOS + 1: Arguments descriptor array.
389 // TOS + 2: IC-data array. 282 // TOS + 2: IC data object.
390 // TOS + 3: Receiver. 283 // TOS + 3: Receiver.
391 // TOS + 4: Place for result from noSuchMethod. 284 // TOS + 4: Space for the result of the runtime call.
392 // TOS + 5: PC marker => RawInstruction object. 285 // TOS + 5: Stub's PC marker (0)
393 // TOS + 6: Saved RBP of previous frame. <== RBP 286 // TOS + 6: Saved FP
394 // TOS + 7: Dart code return address 287 // TOS + 7: Dart code return address
395 // TOS + 8: Last argument of caller. 288 // TOS + 8: Last argument of caller.
396 // .... 289 // ....
397 290
398 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry); 291 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry);
399 // Remove arguments. 292 // Remove arguments.
400 __ popq(RAX); 293 __ popq(RAX);
401 __ popq(RAX); 294 __ popq(RAX);
402 __ popq(RAX); 295 __ popq(RAX);
403 __ popq(RAX); 296 __ popq(RAX);
404 __ popq(RAX); // Get result into RAX. 297 __ popq(RAX); // Get result into RAX.
405
406 // Remove the stub frame as we are about to return.
407 __ LeaveFrame(); 298 __ LeaveFrame();
408 __ ret(); 299 __ ret();
409 } 300 }
410 301
411 302
412 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 303 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
413 intptr_t deopt_reason, 304 intptr_t deopt_reason,
414 uword saved_registers_address); 305 uword saved_registers_address);
415 306
416 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); 307 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { 416 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
526 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX. 417 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX.
527 } 418 }
528 419
529 420
530 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { 421 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
531 AssemblerMacros::EnterStubFrame(assembler); 422 AssemblerMacros::EnterStubFrame(assembler);
532 // Load the receiver into RAX. The argument count in the arguments 423 // Load the receiver into RAX. The argument count in the arguments
533 // descriptor in R10 is a smi. 424 // descriptor in R10 is a smi.
534 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 425 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
535 // Two words (return addres, saved fp) in the stack above the last argument. 426 // Two words (saved fp, stub's pc marker) in the stack above the return
427 // address.
536 __ movq(RAX, Address(RSP, RAX, TIMES_4, 2 * kWordSize)); 428 __ movq(RAX, Address(RSP, RAX, TIMES_4, 2 * kWordSize));
537 // Preserve IC data and arguments descriptor. 429 // Preserve IC data and arguments descriptor.
538 __ pushq(RBX); 430 __ pushq(RBX);
539 __ pushq(R10); 431 __ pushq(R10);
540 432
541 const Immediate raw_null = 433 const Immediate raw_null =
542 Immediate(reinterpret_cast<intptr_t>(Instructions::null())); 434 Immediate(reinterpret_cast<intptr_t>(Instructions::null()));
543 __ pushq(raw_null); // Space for the result of the runtime call. 435 __ pushq(raw_null); // Space for the result of the runtime call.
544 __ pushq(RAX); // Receiver. 436 __ pushq(RAX); // Receiver.
545 __ pushq(RBX); // IC data. 437 __ pushq(RBX); // IC data.
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 // R13: non-closure object. 663 // R13: non-closure object.
772 // R10: arguments descriptor array. 664 // R10: arguments descriptor array.
773 665
774 // Create a stub frame as we are pushing some objects on the stack before 666 // Create a stub frame as we are pushing some objects on the stack before
775 // calling into the runtime. 667 // calling into the runtime.
776 AssemblerMacros::EnterStubFrame(assembler); 668 AssemblerMacros::EnterStubFrame(assembler);
777 669
778 __ pushq(raw_null); // Setup space on stack for result from call. 670 __ pushq(raw_null); // Setup space on stack for result from call.
779 __ pushq(R13); // Non-closure object. 671 __ pushq(R13); // Non-closure object.
780 __ pushq(R10); // Arguments descriptor. 672 __ pushq(R10); // Arguments descriptor.
781 // Load num_args. 673 // Load smi-tagged arguments array length, including the non-closure.
782 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 674 __ movq(R10, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
783 __ SmiUntag(R13); // Arguments array length, including the non-closure.
784 // See stack layout below explaining "wordSize * 6" offset. 675 // See stack layout below explaining "wordSize * 6" offset.
785 PushArgumentsArray(assembler, (kWordSize * 6)); 676 PushArgumentsArray(assembler, (kWordSize * 6));
786 677
787 // Stack: 678 // Stack:
788 // TOS + 0: Argument array. 679 // TOS + 0: Argument array.
789 // TOS + 1: Arguments descriptor array. 680 // TOS + 1: Arguments descriptor array.
790 // TOS + 2: Non-closure object. 681 // TOS + 2: Non-closure object.
791 // TOS + 3: Place for result from the call. 682 // TOS + 3: Place for result from the call.
792 // TOS + 4: PC marker => RawInstruction object. 683 // TOS + 4: PC marker => RawInstruction object.
793 // TOS + 5: Saved RBP of previous frame. <== RBP 684 // TOS + 5: Saved RBP of previous frame. <== RBP
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after
1438 // RBP + 16 : address of last argument (arg n-1). 1329 // RBP + 16 : address of last argument (arg n-1).
1439 // RBP + 16 + 8*(n-1) : address of first argument (arg 0). 1330 // RBP + 16 + 8*(n-1) : address of first argument (arg 0).
1440 // RBX : ic-data. 1331 // RBX : ic-data.
1441 // R10 : arguments descriptor array. 1332 // R10 : arguments descriptor array.
1442 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 1333 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
1443 // The target function was not found, so invoke method 1334 // The target function was not found, so invoke method
1444 // "dynamic noSuchMethod(InvocationMirror invocation)". 1335 // "dynamic noSuchMethod(InvocationMirror invocation)".
1445 const Immediate raw_null = 1336 const Immediate raw_null =
1446 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1337 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1447 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 1338 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
1448 __ SmiUntag(R13); 1339 __ movq(RAX, Address(RBP, R13, TIMES_4, kWordSize)); // Get receiver.
1449 __ movq(RAX, Address(RBP, R13, TIMES_8, kWordSize)); // Get receiver.
1450 1340
1451 // Create a stub frame. 1341 // Create a stub frame.
1452 AssemblerMacros::EnterStubFrame(assembler); 1342 AssemblerMacros::EnterStubFrame(assembler);
1453 1343
1454 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. 1344 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod.
1455 __ pushq(RAX); // Receiver. 1345 __ pushq(RAX); // Receiver.
1456 __ pushq(RBX); // IC data array. 1346 __ pushq(RBX); // IC data array.
1457 __ pushq(R10); // Arguments descriptor array. 1347 __ pushq(R10); // Arguments descriptor array.
1458 // R13: Arguments array length, including the receiver. 1348
1349 __ movq(R10, R13); // Smi-tagged arguments array length.
1459 // See stack layout below explaining "wordSize * 10" offset. 1350 // See stack layout below explaining "wordSize * 10" offset.
1460 PushArgumentsArray(assembler, (kWordSize * 10)); 1351 PushArgumentsArray(assembler, (kWordSize * 10));
1461 1352
1462 // Stack: 1353 // Stack:
1463 // TOS + 0: Argument array. 1354 // TOS + 0: Argument array.
1464 // TOS + 1: Arguments descriptor array. 1355 // TOS + 1: Arguments descriptor array.
1465 // TOS + 2: Ic-data array. 1356 // TOS + 2: Ic-data array.
1466 // TOS + 3: Receiver. 1357 // TOS + 3: Receiver.
1467 // TOS + 4: Place for result from noSuchMethod. 1358 // TOS + 4: Place for result from noSuchMethod.
1468 // TOS + 5: PC marker => RawInstruction object. 1359 // TOS + 5: PC marker => RawInstruction object.
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after
2175 __ cmpq(left, right); 2066 __ cmpq(left, right);
2176 __ Bind(&done); 2067 __ Bind(&done);
2177 __ popq(right); 2068 __ popq(right);
2178 __ popq(left); 2069 __ popq(left);
2179 __ ret(); 2070 __ ret();
2180 } 2071 }
2181 2072
2182 } // namespace dart 2073 } // namespace dart
2183 2074
2184 #endif // defined TARGET_ARCH_X64 2075 #endif // defined TARGET_ARCH_X64
OLDNEW
« runtime/vm/code_generator.cc ('K') | « runtime/vm/stub_code_ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698