| 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 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 | 268 |
| 269 // Preserve values across call to resolving. | 269 // Preserve values across call to resolving. |
| 270 // Stack at this point: | 270 // Stack at this point: |
| 271 // TOS + 0: PC marker => RawInstruction object. | 271 // TOS + 0: PC marker => RawInstruction object. |
| 272 // TOS + 1: Saved RBP of previous frame. <== RBP | 272 // TOS + 1: Saved RBP of previous frame. <== RBP |
| 273 // TOS + 2: Dart code return address | 273 // TOS + 2: Dart code return address |
| 274 // TOS + 3: Last argument of caller. | 274 // TOS + 3: Last argument of caller. |
| 275 // .... | 275 // .... |
| 276 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 276 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 277 __ movq(RAX, Address(RBP, RAX, TIMES_4, kWordSize)); // Get receiver. | 277 __ movq(RAX, Address(RBP, RAX, TIMES_4, kWordSize)); // Get receiver. |
| 278 __ pushq(R10); // Preserve arguments descriptor array. | |
| 279 __ pushq(RAX); // Preserve receiver. | |
| 280 __ pushq(RBX); // Preserve ic-data. | |
| 281 // First resolve the function to get the function object. | |
| 282 | |
| 283 __ pushq(raw_null); // Setup space on stack for return value. | |
| 284 __ pushq(RAX); // Pass receiver. | |
| 285 __ pushq(RBX); // Pass IC data object. | |
| 286 __ pushq(R10); // Pass arguments descriptor array. | |
| 287 __ CallRuntime(kResolveCompileInstanceFunctionRuntimeEntry); | |
| 288 __ popq(RAX); // Remove arguments pushed earlier. | |
| 289 __ popq(RAX); | |
| 290 __ popq(RAX); | |
| 291 __ popq(RBX); // Pop returned code object into RBX. | |
| 292 // Pop preserved values | |
| 293 __ popq(R10); // Restore ic-data. | |
| 294 __ popq(RAX); // Restore receiver. | |
| 295 __ popq(R13); // Restore arguments descriptor array. | |
| 296 | |
| 297 __ cmpq(RBX, raw_null); | |
| 298 Label check_implicit_closure; | |
| 299 __ j(EQUAL, &check_implicit_closure, Assembler::kNearJump); | |
| 300 | |
| 301 // Remove the stub frame as we are about to jump to the dart function. | |
| 302 __ LeaveFrame(); | |
| 303 | |
| 304 __ movq(R10, R13); | |
| 305 __ movq(RBX, FieldAddress(RBX, Code::instructions_offset())); | |
| 306 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | |
| 307 __ jmp(RBX); | |
| 308 | |
| 309 __ Bind(&check_implicit_closure); | |
| 310 // RAX: receiver. | 278 // RAX: receiver. |
| 311 // R10: ic-data. | 279 // RBX: ic-data. |
| 312 // RBX: raw_null. | 280 // R10: arguments descriptor array. |
| 313 // R13: arguments descriptor array. | |
| 314 // The target function was not found. | 281 // The target function was not found. |
| 315 // First check to see if this is a getter function and we are | 282 // First check to see if this is a getter function and we are |
| 316 // trying to create a closure of an instance function. | 283 // trying to create a closure of an instance function. |
| 317 // Push values that need to be preserved across runtime call. | 284 // Push values that need to be preserved across runtime call. |
| 318 __ pushq(RAX); // Preserve receiver. | 285 __ pushq(RAX); // Preserve receiver. |
| 319 __ pushq(R10); // Preserve ic-data. | 286 __ pushq(RBX); // Preserve ic-data. |
| 320 __ pushq(R13); // Preserve arguments descriptor array. | 287 __ pushq(R10); // Preserve arguments descriptor array. |
| 321 | 288 |
| 322 __ pushq(raw_null); // Setup space on stack for return value. | 289 __ pushq(raw_null); // Setup space on stack for return value. |
| 323 __ pushq(RAX); // Push receiver. | 290 __ pushq(RAX); // Push receiver. |
| 324 __ pushq(R10); // Ic-data array. | 291 __ pushq(RBX); // Ic-data array. |
| 325 __ CallRuntime(kResolveImplicitClosureFunctionRuntimeEntry); | 292 __ CallRuntime(kResolveImplicitClosureFunctionRuntimeEntry); |
| 326 __ popq(RAX); | 293 __ popq(RAX); |
| 327 __ popq(RAX); | 294 __ popq(RAX); |
| 328 __ popq(RBX); // Get return value into RBX, might be Closure object. | 295 __ popq(RCX); // Get return value into RCX, might be Closure object. |
| 329 | 296 |
| 330 // Pop preserved values. | 297 // Pop preserved values. |
| 331 __ popq(R13); // Restore arguments descriptor array. | 298 __ popq(R10); // Restore arguments descriptor array. |
| 332 __ popq(R10); // Restore ic-data. | 299 __ popq(RBX); // Restore ic-data. |
| 333 __ popq(RAX); // Restore receiver. | 300 __ popq(RAX); // Restore receiver. |
| 334 | 301 |
| 335 __ cmpq(RBX, raw_null); | 302 __ cmpq(RCX, raw_null); |
| 336 Label check_implicit_closure_through_getter; | 303 Label check_implicit_closure_through_getter; |
| 337 __ j(EQUAL, &check_implicit_closure_through_getter, Assembler::kNearJump); | 304 __ j(EQUAL, &check_implicit_closure_through_getter, Assembler::kNearJump); |
| 338 | 305 |
| 339 __ movq(RAX, RBX); // Return value is the closure object. | 306 __ movq(RAX, RCX); // Return value is the closure object. |
| 340 // Remove the stub frame as we are about return. | 307 // Remove the stub frame as we are about return. |
| 341 __ LeaveFrame(); | 308 __ LeaveFrame(); |
| 342 __ ret(); | 309 __ ret(); |
| 343 | 310 |
| 344 __ Bind(&check_implicit_closure_through_getter); | 311 __ Bind(&check_implicit_closure_through_getter); |
| 345 // RAX: receiver. | 312 // RAX: receiver. |
| 346 // R10: ic-data. | 313 // RBX: ic-data. |
| 347 // RBX: raw_null. | 314 // R10: arguments descriptor array. |
| 348 // R13: arguments descriptor array. | |
| 349 // This is not the case of an instance so invoke the getter of the | 315 // This is not the case of an instance so invoke the getter of the |
| 350 // same name and see if we get a closure back which we are then | 316 // same name and see if we get a closure back which we are then |
| 351 // supposed to invoke. | 317 // supposed to invoke. |
| 352 // Push values that need to be preserved across runtime call. | 318 // Push values that need to be preserved across runtime call. |
| 353 __ pushq(RAX); // Preserve receiver. | 319 __ pushq(RAX); // Preserve receiver. |
| 354 __ pushq(R10); // Preserve ic-data. | 320 __ pushq(RBX); // Preserve ic-data. |
| 355 __ pushq(R13); // Preserve arguments descriptor array. | 321 __ pushq(R10); // Preserve arguments descriptor array. |
| 356 | 322 |
| 357 __ pushq(raw_null); // Setup space on stack for return value. | 323 __ pushq(raw_null); // Setup space on stack for return value. |
| 358 __ pushq(RAX); // Push receiver. | 324 __ pushq(RAX); // Push receiver. |
| 359 __ pushq(R10); // Ic-data array. | 325 __ pushq(RBX); // Ic-data array. |
| 360 __ CallRuntime(kResolveImplicitClosureThroughGetterRuntimeEntry); | 326 __ CallRuntime(kResolveImplicitClosureThroughGetterRuntimeEntry); |
| 361 __ popq(R10); // Pop argument. | |
| 362 __ popq(RAX); // Pop argument. | 327 __ popq(RAX); // Pop argument. |
| 363 __ popq(RBX); // get return value into RBX, might be Closure object. | 328 __ popq(RAX); // Pop argument. |
| 329 __ popq(RCX); // get return value into RCX, might be Closure object. |
| 364 | 330 |
| 365 // Pop preserved values. | 331 // Pop preserved values. |
| 366 __ popq(R13); // Restore arguments descriptor array. | 332 __ popq(R10); // Restore arguments descriptor array. |
| 367 __ popq(R10); // Restore ic-data. | 333 __ popq(RBX); // Restore ic-data. |
| 368 __ popq(RAX); // Restore receiver. | 334 __ popq(RAX); // Restore receiver. |
| 369 | 335 |
| 370 __ cmpq(RBX, raw_null); | 336 __ cmpq(RCX, raw_null); |
| 371 Label function_not_found; | 337 Label function_not_found; |
| 372 __ j(EQUAL, &function_not_found); | 338 __ j(EQUAL, &function_not_found, Assembler::kNearJump); |
| 373 | 339 |
| 374 // RBX: Closure object. | 340 // RCX: Closure object. |
| 375 // R13: Arguments descriptor array. | 341 // R10: Arguments descriptor array. |
| 376 __ 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. |
| 377 __ pushq(RBX); // Closure object. | 343 __ pushq(RCX); // Closure object. |
| 378 __ pushq(R13); // Arguments descriptor. | 344 __ pushq(R10); // Arguments descriptor. |
| 379 __ movq(R13, FieldAddress(R13, ArgumentsDescriptor::count_offset())); | 345 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 380 __ SmiUntag(R13); | 346 __ SmiUntag(R13); |
| 381 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver. | 347 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver. |
| 382 PushArgumentsArray(assembler, (kWordSize * 6)); | 348 PushArgumentsArray(assembler, (kWordSize * 6)); |
| 383 // Stack layout explaining "(kWordSize * 6)" offset. | 349 // Stack layout explaining "(kWordSize * 6)" offset. |
| 384 // TOS + 0: Argument array. | 350 // TOS + 0: Argument array. |
| 385 // TOS + 1: Arguments descriptor array. | 351 // TOS + 1: Arguments descriptor array. |
| 386 // TOS + 2: Closure object. | 352 // TOS + 2: Closure object. |
| 387 // TOS + 3: Place for result from closure function. | 353 // TOS + 3: Place for result from closure function. |
| 388 // TOS + 4: PC marker => RawInstruction object. | 354 // TOS + 4: PC marker => RawInstruction object. |
| 389 // TOS + 5: Saved RBP of previous frame. <== RBP | 355 // TOS + 5: Saved RBP of previous frame. <== RBP |
| 390 // TOS + 6: Dart code return address | 356 // TOS + 6: Dart code return address |
| 391 // TOS + 7: Last argument of caller. | 357 // TOS + 7: Last argument of caller. |
| 392 // .... | 358 // .... |
| 393 | 359 |
| 394 __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry); | 360 __ CallRuntime(kInvokeImplicitClosureFunctionRuntimeEntry); |
| 395 // Remove arguments. | 361 // Remove arguments. |
| 396 __ popq(RAX); | 362 __ popq(RAX); |
| 397 __ popq(RAX); | 363 __ popq(RAX); |
| 398 __ popq(RAX); | 364 __ popq(RAX); |
| 399 __ popq(RAX); // Get result into RAX. | 365 __ popq(RAX); // Get result into RAX. |
| 400 | 366 |
| 401 // Remove the stub frame as we are about to return. | 367 // Remove the stub frame as we are about to return. |
| 402 __ LeaveFrame(); | 368 __ LeaveFrame(); |
| 403 __ ret(); | 369 __ ret(); |
| 404 | 370 |
| 405 __ Bind(&function_not_found); | 371 __ Bind(&function_not_found); |
| 406 // The target function was not found, so invoke method | 372 // The target function was not found, so invoke method |
| 407 // "void noSuchMethod(function_name, args_array)". | 373 // "void noSuchMethod(function_name, args_array)". |
| 408 // RAX: receiver. | 374 // RAX: receiver. |
| 409 // R10: ic-data. | 375 // RBX: ic-data. |
| 410 // RBX: raw_null. | 376 // R10: arguments descriptor array. |
| 411 // R13: arguments descriptor array. | |
| 412 | 377 |
| 413 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. | 378 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. |
| 414 __ pushq(RAX); // Receiver. | 379 __ pushq(RAX); // Receiver. |
| 415 __ pushq(R10); // IC-data array. | 380 __ pushq(RBX); // IC-data array. |
| 416 __ pushq(R13); // Arguments descriptor array. | 381 __ pushq(R10); // Arguments descriptor array. |
| 417 __ movq(R13, FieldAddress(R13, ArgumentsDescriptor::count_offset())); | 382 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 418 __ SmiUntag(R13); | 383 __ SmiUntag(R13); |
| 419 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver. | 384 __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver. |
| 420 // See stack layout below explaining "wordSize * 7" offset. | 385 // See stack layout below explaining "wordSize * 7" offset. |
| 421 PushArgumentsArray(assembler, (kWordSize * 7)); | 386 PushArgumentsArray(assembler, (kWordSize * 7)); |
| 422 | 387 |
| 423 // Stack: | 388 // Stack: |
| 424 // TOS + 0: Arguments array. | 389 // TOS + 0: Arguments array. |
| 425 // TOS + 1: Arguments descriptor array. | 390 // TOS + 1: Arguments descriptor array. |
| 426 // TOS + 2: IC-data array. | 391 // TOS + 2: IC-data array. |
| 427 // TOS + 3: Receiver. | 392 // TOS + 3: Receiver. |
| (...skipping 1739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2167 __ cmpq(left, right); | 2132 __ cmpq(left, right); |
| 2168 __ Bind(&done); | 2133 __ Bind(&done); |
| 2169 __ popq(right); | 2134 __ popq(right); |
| 2170 __ popq(left); | 2135 __ popq(left); |
| 2171 __ ret(); | 2136 __ ret(); |
| 2172 } | 2137 } |
| 2173 | 2138 |
| 2174 } // namespace dart | 2139 } // namespace dart |
| 2175 | 2140 |
| 2176 #endif // defined TARGET_ARCH_X64 | 2141 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |