OLD | NEW |
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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 __ cmpq(RCX, raw_null); | 336 __ cmpq(RCX, raw_null); |
337 Label function_not_found; | 337 Label function_not_found; |
338 __ j(EQUAL, &function_not_found); | 338 __ j(EQUAL, &function_not_found); |
339 | 339 |
340 // RCX: Closure object. | 340 // RCX: Closure object. |
341 // R10: Arguments descriptor array. | 341 // R10: Arguments descriptor array. |
342 __ pushq(raw_null); // Setup space on stack for result from invoking Closure. | 342 __ pushq(raw_null); // Setup space on stack for result from invoking Closure. |
343 __ pushq(RCX); // Closure object. | 343 __ pushq(RCX); // Closure object. |
344 __ pushq(R10); // Arguments descriptor. | 344 __ pushq(R10); // Arguments descriptor. |
345 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 345 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
346 __ SmiUntag(R13); | 346 __ SmiUntag(R13); // Arguments array length, including the original receiver. |
347 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver. | |
348 PushArgumentsArray(assembler, (kWordSize * 6)); | 347 PushArgumentsArray(assembler, (kWordSize * 6)); |
349 // Stack layout explaining "(kWordSize * 6)" offset. | 348 // Stack layout explaining "(kWordSize * 6)" offset. |
350 // TOS + 0: Argument array. | 349 // TOS + 0: Argument array. |
351 // TOS + 1: Arguments descriptor array. | 350 // TOS + 1: Arguments descriptor array. |
352 // TOS + 2: Closure object. | 351 // TOS + 2: Closure object. |
353 // TOS + 3: Place for result from closure function. | 352 // TOS + 3: Place for result from closure function. |
354 // TOS + 4: PC marker => RawInstruction object. | 353 // TOS + 4: PC marker => RawInstruction object. |
355 // TOS + 5: Saved RBP of previous frame. <== RBP | 354 // TOS + 5: Saved RBP of previous frame. <== RBP |
356 // TOS + 6: Dart code return address | 355 // TOS + 6: Dart code return address |
357 // TOS + 7: Last argument of caller. | 356 // TOS + 7: Last argument of caller. |
358 // .... | 357 // .... |
359 | 358 |
360 __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry); | 359 __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry); |
361 // Remove arguments. | 360 // Remove arguments. |
362 __ popq(RAX); | 361 __ popq(RAX); |
363 __ popq(RAX); | 362 __ popq(RAX); |
364 __ popq(RAX); | 363 __ popq(RAX); |
365 __ popq(RAX); // Get result into RAX. | 364 __ popq(RAX); // Get result into RAX. |
366 | 365 |
367 // Remove the stub frame as we are about to return. | 366 // Remove the stub frame as we are about to return. |
368 __ LeaveFrame(); | 367 __ LeaveFrame(); |
369 __ ret(); | 368 __ ret(); |
370 | 369 |
371 __ Bind(&function_not_found); | 370 __ Bind(&function_not_found); |
372 // The target function was not found, so invoke method | 371 // The target function was not found, so invoke method |
373 // "void noSuchMethod(function_name, args_array)". | 372 // "dynamic noSuchMethod(InvocationMirror invocation)". |
374 // RAX: receiver. | 373 // RAX: receiver. |
375 // RBX: ic-data. | 374 // RBX: ic-data. |
376 // R10: arguments descriptor array. | 375 // R10: arguments descriptor array. |
377 | 376 |
378 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. | 377 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. |
379 __ pushq(RAX); // Receiver. | 378 __ pushq(RAX); // Receiver. |
380 __ pushq(RBX); // IC-data array. | 379 __ pushq(RBX); // IC-data array. |
381 __ pushq(R10); // Arguments descriptor array. | 380 __ pushq(R10); // Arguments descriptor array. |
382 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 381 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
383 __ SmiUntag(R13); | 382 __ SmiUntag(R13); // Arguments array length, including the original receiver. |
384 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver. | |
385 // See stack layout below explaining "wordSize * 7" offset. | 383 // See stack layout below explaining "wordSize * 7" offset. |
386 PushArgumentsArray(assembler, (kWordSize * 7)); | 384 PushArgumentsArray(assembler, (kWordSize * 7)); |
387 | 385 |
388 // Stack: | 386 // Stack: |
389 // TOS + 0: Arguments array. | 387 // TOS + 0: Arguments array. |
390 // TOS + 1: Arguments descriptor array. | 388 // TOS + 1: Arguments descriptor array. |
391 // TOS + 2: IC-data array. | 389 // TOS + 2: IC-data array. |
392 // TOS + 3: Receiver. | 390 // TOS + 3: Receiver. |
393 // TOS + 4: Place for result from noSuchMethod. | 391 // TOS + 4: Place for result from noSuchMethod. |
394 // TOS + 5: PC marker => RawInstruction object. | 392 // TOS + 5: PC marker => RawInstruction object. |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
769 // R10: arguments descriptor array. | 767 // R10: arguments descriptor array. |
770 | 768 |
771 // Create a stub frame as we are pushing some objects on the stack before | 769 // Create a stub frame as we are pushing some objects on the stack before |
772 // calling into the runtime. | 770 // calling into the runtime. |
773 AssemblerMacros::EnterStubFrame(assembler); | 771 AssemblerMacros::EnterStubFrame(assembler); |
774 | 772 |
775 __ pushq(raw_null); // Setup space on stack for result from error reporting. | 773 __ pushq(raw_null); // Setup space on stack for result from error reporting. |
776 __ pushq(R13); // Non-closure object. | 774 __ pushq(R13); // Non-closure object. |
777 // Load num_args. | 775 // Load num_args. |
778 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 776 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
779 __ SmiUntag(R13); | 777 __ SmiUntag(R13); // Arguments array length, including the non-closure. |
780 __ subq(R13, Immediate(1)); // Arguments array length, minus the closure. | |
781 // See stack layout below explaining "wordSize * 5" offset. | 778 // See stack layout below explaining "wordSize * 5" offset. |
782 PushArgumentsArray(assembler, (kWordSize * 5)); | 779 PushArgumentsArray(assembler, (kWordSize * 5)); |
783 | 780 |
784 // Stack: | 781 // Stack: |
785 // TOS + 0: Argument array. | 782 // TOS + 0: Argument array. |
786 // TOS + 1: Non-closure object. | 783 // TOS + 1: Non-closure object. |
787 // TOS + 2: Place for result from reporting the error. | 784 // TOS + 2: Place for result from reporting the error. |
788 // TOS + 3: PC marker => RawInstruction object. | 785 // TOS + 3: PC marker => RawInstruction object. |
789 // TOS + 4: Saved RBP of previous frame. <== RBP | 786 // TOS + 4: Saved RBP of previous frame. <== RBP |
790 // TOS + 5: Dart code return address | 787 // TOS + 5: Dart code return address |
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1422 // Input parameters: | 1419 // Input parameters: |
1423 // RBP - 8 : PC marker => RawInstruction object. | 1420 // RBP - 8 : PC marker => RawInstruction object. |
1424 // RBP : points to previous frame pointer. | 1421 // RBP : points to previous frame pointer. |
1425 // RBP + 8 : points to return address. | 1422 // RBP + 8 : points to return address. |
1426 // RBP + 16 : address of last argument (arg n-1). | 1423 // RBP + 16 : address of last argument (arg n-1). |
1427 // RBP + 16 + 8*(n-1) : address of first argument (arg 0). | 1424 // RBP + 16 + 8*(n-1) : address of first argument (arg 0). |
1428 // RBX : ic-data. | 1425 // RBX : ic-data. |
1429 // R10 : arguments descriptor array. | 1426 // R10 : arguments descriptor array. |
1430 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { | 1427 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { |
1431 // The target function was not found, so invoke method | 1428 // The target function was not found, so invoke method |
1432 // "void noSuchMethod(function_name, Array arguments)". | 1429 // "dynamic noSuchMethod(InvocationMirror invocation)". |
1433 // TODO(regis): For now, we simply pass the actual arguments, both positional | |
1434 // and named, as the argument array. This is not correct if out-of-order | |
1435 // named arguments were passed. | |
1436 // The signature of the "noSuchMethod" method has to change from | |
1437 // noSuchMethod(String name, Array arguments) to something like | |
1438 // noSuchMethod(InvocationMirror call). | |
1439 // Also, the class NoSuchMethodError has to be modified accordingly. | |
1440 const Immediate raw_null = | 1430 const Immediate raw_null = |
1441 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1431 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
1442 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 1432 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
1443 __ SmiUntag(R13); | 1433 __ SmiUntag(R13); |
1444 __ movq(RAX, Address(RBP, R13, TIMES_8, kWordSize)); // Get receiver. | 1434 __ movq(RAX, Address(RBP, R13, TIMES_8, kWordSize)); // Get receiver. |
1445 | 1435 |
1446 // Create a stub frame. | 1436 // Create a stub frame. |
1447 AssemblerMacros::EnterStubFrame(assembler); | 1437 AssemblerMacros::EnterStubFrame(assembler); |
1448 | 1438 |
1449 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. | 1439 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. |
1450 __ pushq(RAX); // Receiver. | 1440 __ pushq(RAX); // Receiver. |
1451 __ pushq(RBX); // IC data array. | 1441 __ pushq(RBX); // IC data array. |
1452 __ pushq(R10); // Arguments descriptor array. | 1442 __ pushq(R10); // Arguments descriptor array. |
1453 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver. | 1443 // R13: Arguments array length, including the receiver. |
1454 // See stack layout below explaining "wordSize * 10" offset. | 1444 // See stack layout below explaining "wordSize * 10" offset. |
1455 PushArgumentsArray(assembler, (kWordSize * 10)); | 1445 PushArgumentsArray(assembler, (kWordSize * 10)); |
1456 | 1446 |
1457 // Stack: | 1447 // Stack: |
1458 // TOS + 0: Argument array. | 1448 // TOS + 0: Argument array. |
1459 // TOS + 1: Arguments descriptor array. | 1449 // TOS + 1: Arguments descriptor array. |
1460 // TOS + 2: Ic-data array. | 1450 // TOS + 2: Ic-data array. |
1461 // TOS + 3: Receiver. | 1451 // TOS + 3: Receiver. |
1462 // TOS + 4: Place for result from noSuchMethod. | 1452 // TOS + 4: Place for result from noSuchMethod. |
1463 // TOS + 5: PC marker => RawInstruction object. | 1453 // TOS + 5: PC marker => RawInstruction object. |
(...skipping 707 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2171 __ cmpq(left, right); | 2161 __ cmpq(left, right); |
2172 __ Bind(&done); | 2162 __ Bind(&done); |
2173 __ popq(right); | 2163 __ popq(right); |
2174 __ popq(left); | 2164 __ popq(left); |
2175 __ ret(); | 2165 __ ret(); |
2176 } | 2166 } |
2177 | 2167 |
2178 } // namespace dart | 2168 } // namespace dart |
2179 | 2169 |
2180 #endif // defined TARGET_ARCH_X64 | 2170 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |