| 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 |