| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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" | |
| 10 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 11 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| 12 #include "vm/flow_graph_compiler.h" | 11 #include "vm/flow_graph_compiler.h" |
| 13 #include "vm/instructions.h" | 12 #include "vm/instructions.h" |
| 14 #include "vm/object_store.h" | 13 #include "vm/object_store.h" |
| 15 #include "vm/pages.h" | 14 #include "vm/pages.h" |
| 16 #include "vm/resolver.h" | 15 #include "vm/resolver.h" |
| 17 #include "vm/scavenger.h" | 16 #include "vm/scavenger.h" |
| 18 #include "vm/stub_code.h" | 17 #include "vm/stub_code.h" |
| 19 | 18 |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 __ LeaveFrame(); | 179 __ LeaveFrame(); |
| 181 __ ret(); | 180 __ ret(); |
| 182 } | 181 } |
| 183 | 182 |
| 184 | 183 |
| 185 // Input parameters: | 184 // Input parameters: |
| 186 // R10: arguments descriptor array. | 185 // R10: arguments descriptor array. |
| 187 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 186 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
| 188 const Immediate& raw_null = | 187 const Immediate& raw_null = |
| 189 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 188 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 190 AssemblerMacros::EnterStubFrame(assembler); | 189 __ EnterStubFrame(); |
| 191 __ pushq(R10); // Preserve arguments descriptor array. | 190 __ pushq(R10); // Preserve arguments descriptor array. |
| 192 __ pushq(raw_null); // Setup space on stack for return value. | 191 __ pushq(raw_null); // Setup space on stack for return value. |
| 193 __ CallRuntime(kPatchStaticCallRuntimeEntry); | 192 __ CallRuntime(kPatchStaticCallRuntimeEntry); |
| 194 __ popq(RAX); // Get Code object result. | 193 __ popq(RAX); // Get Code object result. |
| 195 __ popq(R10); // Restore arguments descriptor array. | 194 __ popq(R10); // Restore arguments descriptor array. |
| 196 // Remove the stub frame as we are about to jump to the dart function. | 195 // Remove the stub frame as we are about to jump to the dart function. |
| 197 __ LeaveFrame(); | 196 __ LeaveFrame(); |
| 198 | 197 |
| 199 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); | 198 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); |
| 200 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 199 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 201 __ jmp(RBX); | 200 __ jmp(RBX); |
| 202 } | 201 } |
| 203 | 202 |
| 204 | 203 |
| 205 // Called from a static call only when an invalid code has been entered | 204 // Called from a static call only when an invalid code has been entered |
| 206 // (invalid because its function was optimized or deoptimized). | 205 // (invalid because its function was optimized or deoptimized). |
| 207 // R10: arguments descriptor array. | 206 // R10: arguments descriptor array. |
| 208 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 207 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
| 209 const Immediate& raw_null = | 208 const Immediate& raw_null = |
| 210 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 209 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 211 AssemblerMacros::EnterStubFrame(assembler); | 210 __ EnterStubFrame(); |
| 212 __ pushq(R10); // Preserve arguments descriptor array. | 211 __ pushq(R10); // Preserve arguments descriptor array. |
| 213 __ pushq(raw_null); // Setup space on stack for return value. | 212 __ pushq(raw_null); // Setup space on stack for return value. |
| 214 __ CallRuntime(kFixCallersTargetRuntimeEntry); | 213 __ CallRuntime(kFixCallersTargetRuntimeEntry); |
| 215 __ popq(RAX); // Get Code object. | 214 __ popq(RAX); // Get Code object. |
| 216 __ popq(R10); // Restore arguments descriptor array. | 215 __ popq(R10); // Restore arguments descriptor array. |
| 217 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | 216 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
| 218 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 217 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 219 __ LeaveFrame(); | 218 __ LeaveFrame(); |
| 220 __ jmp(RAX); | 219 __ jmp(RAX); |
| 221 __ int3(); | 220 __ int3(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 250 } | 249 } |
| 251 | 250 |
| 252 | 251 |
| 253 // Input parameters: | 252 // Input parameters: |
| 254 // RBX: ic-data. | 253 // RBX: ic-data. |
| 255 // R10: arguments descriptor array. | 254 // R10: arguments descriptor array. |
| 256 // Note: The receiver object is the first argument to the function being | 255 // Note: The receiver object is the first argument to the function being |
| 257 // called, the stub accesses the receiver from this location directly | 256 // called, the stub accesses the receiver from this location directly |
| 258 // when trying to resolve the call. | 257 // when trying to resolve the call. |
| 259 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { | 258 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { |
| 260 AssemblerMacros::EnterStubFrame(assembler); | 259 __ EnterStubFrame(); |
| 261 | 260 |
| 262 const Immediate& raw_null = | 261 const Immediate& raw_null = |
| 263 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 262 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 264 __ pushq(raw_null); // Space for the return value. | 263 __ pushq(raw_null); // Space for the return value. |
| 265 | 264 |
| 266 // Push the receiver as an argument. Load the smi-tagged argument | 265 // Push the receiver as an argument. Load the smi-tagged argument |
| 267 // count into R13 to index the receiver in the stack. There are | 266 // count into R13 to index the receiver in the stack. There are |
| 268 // three words (null, stub's pc marker, saved fp) above the return | 267 // three words (null, stub's pc marker, saved fp) above the return |
| 269 // address. | 268 // address. |
| 270 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 269 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 // Restore result into RBX. | 379 // Restore result into RBX. |
| 381 __ movq(RBX, Address(RBP, -1 * kWordSize)); | 380 __ movq(RBX, Address(RBP, -1 * kWordSize)); |
| 382 } | 381 } |
| 383 // Code above cannot cause GC. | 382 // Code above cannot cause GC. |
| 384 __ LeaveFrame(); | 383 __ LeaveFrame(); |
| 385 __ movq(RBP, RAX); | 384 __ movq(RBP, RAX); |
| 386 | 385 |
| 387 // Frame is fully rewritten at this point and it is safe to perform a GC. | 386 // Frame is fully rewritten at this point and it is safe to perform a GC. |
| 388 // Materialize any objects that were deferred by FillFrame because they | 387 // Materialize any objects that were deferred by FillFrame because they |
| 389 // require allocation. | 388 // require allocation. |
| 390 AssemblerMacros::EnterStubFrame(assembler); | 389 __ EnterStubFrame(); |
| 391 if (preserve_rax) { | 390 if (preserve_rax) { |
| 392 __ pushq(RBX); // Preserve result, it will be GC-d here. | 391 __ pushq(RBX); // Preserve result, it will be GC-d here. |
| 393 } | 392 } |
| 394 __ CallRuntime(kDeoptimizeMaterializeDoublesRuntimeEntry); | 393 __ CallRuntime(kDeoptimizeMaterializeDoublesRuntimeEntry); |
| 395 if (preserve_rax) { | 394 if (preserve_rax) { |
| 396 __ popq(RAX); // Restore result. | 395 __ popq(RAX); // Restore result. |
| 397 } | 396 } |
| 398 __ LeaveFrame(); | 397 __ LeaveFrame(); |
| 399 | 398 |
| 400 __ ret(); | 399 __ ret(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 412 GenerateDeoptimizationSequence(assembler, true); // Preserve RAX. | 411 GenerateDeoptimizationSequence(assembler, true); // Preserve RAX. |
| 413 } | 412 } |
| 414 | 413 |
| 415 | 414 |
| 416 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { | 415 void StubCode::GenerateDeoptimizeStub(Assembler* assembler) { |
| 417 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX. | 416 GenerateDeoptimizationSequence(assembler, false); // Don't preserve RAX. |
| 418 } | 417 } |
| 419 | 418 |
| 420 | 419 |
| 421 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { | 420 void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) { |
| 422 AssemblerMacros::EnterStubFrame(assembler); | 421 __ EnterStubFrame(); |
| 423 // Load the receiver into RAX. The argument count in the arguments | 422 // Load the receiver into RAX. The argument count in the arguments |
| 424 // descriptor in R10 is a smi. | 423 // descriptor in R10 is a smi. |
| 425 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 424 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 426 // Two words (saved fp, stub's pc marker) in the stack above the return | 425 // Two words (saved fp, stub's pc marker) in the stack above the return |
| 427 // address. | 426 // address. |
| 428 __ movq(RAX, Address(RSP, RAX, TIMES_4, 2 * kWordSize)); | 427 __ movq(RAX, Address(RSP, RAX, TIMES_4, 2 * kWordSize)); |
| 429 // Preserve IC data and arguments descriptor. | 428 // Preserve IC data and arguments descriptor. |
| 430 __ pushq(RBX); | 429 __ pushq(RBX); |
| 431 __ pushq(R10); | 430 __ pushq(R10); |
| 432 | 431 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 // RAX: new object. | 569 // RAX: new object. |
| 571 // R10: Array length as Smi (preserved for the caller.) | 570 // R10: Array length as Smi (preserved for the caller.) |
| 572 __ ret(); | 571 __ ret(); |
| 573 } | 572 } |
| 574 | 573 |
| 575 // Unable to allocate the array using the fast inline code, just call | 574 // Unable to allocate the array using the fast inline code, just call |
| 576 // into the runtime. | 575 // into the runtime. |
| 577 __ Bind(&slow_case); | 576 __ Bind(&slow_case); |
| 578 // Create a stub frame as we are pushing some objects on the stack before | 577 // Create a stub frame as we are pushing some objects on the stack before |
| 579 // calling into the runtime. | 578 // calling into the runtime. |
| 580 AssemblerMacros::EnterStubFrame(assembler); | 579 __ EnterStubFrame(); |
| 581 __ pushq(raw_null); // Setup space on stack for return value. | 580 __ pushq(raw_null); // Setup space on stack for return value. |
| 582 __ pushq(R10); // Array length as Smi. | 581 __ pushq(R10); // Array length as Smi. |
| 583 __ pushq(RBX); // Element type. | 582 __ pushq(RBX); // Element type. |
| 584 __ CallRuntime(kAllocateArrayRuntimeEntry); | 583 __ CallRuntime(kAllocateArrayRuntimeEntry); |
| 585 __ popq(RAX); // Pop element type argument. | 584 __ popq(RAX); // Pop element type argument. |
| 586 __ popq(R10); // Pop array length argument. | 585 __ popq(R10); // Pop array length argument. |
| 587 __ popq(RAX); // Pop return value from return slot. | 586 __ popq(RAX); // Pop return value from return slot. |
| 588 __ LeaveFrame(); | 587 __ LeaveFrame(); |
| 589 __ ret(); | 588 __ ret(); |
| 590 } | 589 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 626 __ movq(CTX, FieldAddress(R13, Closure::context_offset())); | 625 __ movq(CTX, FieldAddress(R13, Closure::context_offset())); |
| 627 | 626 |
| 628 // Load closure function code in RAX. | 627 // Load closure function code in RAX. |
| 629 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | 628 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); |
| 630 __ cmpq(RAX, raw_null); | 629 __ cmpq(RAX, raw_null); |
| 631 Label function_compiled; | 630 Label function_compiled; |
| 632 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); | 631 __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump); |
| 633 | 632 |
| 634 // Create a stub frame as we are pushing some objects on the stack before | 633 // Create a stub frame as we are pushing some objects on the stack before |
| 635 // calling into the runtime. | 634 // calling into the runtime. |
| 636 AssemblerMacros::EnterStubFrame(assembler); | 635 __ EnterStubFrame(); |
| 637 | 636 |
| 638 __ pushq(R10); // Preserve arguments descriptor array. | 637 __ pushq(R10); // Preserve arguments descriptor array. |
| 639 __ pushq(RBX); // Preserve read-only function object argument. | 638 __ pushq(RBX); // Preserve read-only function object argument. |
| 640 __ CallRuntime(kCompileFunctionRuntimeEntry); | 639 __ CallRuntime(kCompileFunctionRuntimeEntry); |
| 641 __ popq(RBX); // Restore read-only function object argument in RBX. | 640 __ popq(RBX); // Restore read-only function object argument in RBX. |
| 642 __ popq(R10); // Restore arguments descriptor array. | 641 __ popq(R10); // Restore arguments descriptor array. |
| 643 // Restore RAX. | 642 // Restore RAX. |
| 644 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); | 643 __ movq(RAX, FieldAddress(RBX, Function::code_offset())); |
| 645 | 644 |
| 646 // Remove the stub frame as we are about to jump to the closure function. | 645 // Remove the stub frame as we are about to jump to the closure function. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 658 __ Bind(¬_closure); | 657 __ Bind(¬_closure); |
| 659 // Call runtime to attempt to resolve and invoke a call method on a | 658 // Call runtime to attempt to resolve and invoke a call method on a |
| 660 // non-closure object, passing the non-closure object and its arguments array, | 659 // non-closure object, passing the non-closure object and its arguments array, |
| 661 // returning here. | 660 // returning here. |
| 662 // If no call method exists, throw a NoSuchMethodError. | 661 // If no call method exists, throw a NoSuchMethodError. |
| 663 // R13: non-closure object. | 662 // R13: non-closure object. |
| 664 // R10: arguments descriptor array. | 663 // R10: arguments descriptor array. |
| 665 | 664 |
| 666 // Create a stub frame as we are pushing some objects on the stack before | 665 // Create a stub frame as we are pushing some objects on the stack before |
| 667 // calling into the runtime. | 666 // calling into the runtime. |
| 668 AssemblerMacros::EnterStubFrame(assembler); | 667 __ EnterStubFrame(); |
| 669 | 668 |
| 670 __ pushq(raw_null); // Setup space on stack for result from call. | 669 __ pushq(raw_null); // Setup space on stack for result from call. |
| 671 __ pushq(R10); // Arguments descriptor. | 670 __ pushq(R10); // Arguments descriptor. |
| 672 // Load smi-tagged arguments array length, including the non-closure. | 671 // Load smi-tagged arguments array length, including the non-closure. |
| 673 __ movq(R10, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 672 __ movq(R10, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 674 // See stack layout below explaining "wordSize * 5" offset. | 673 // See stack layout below explaining "wordSize * 5" offset. |
| 675 PushArgumentsArray(assembler, (kWordSize * 5)); | 674 PushArgumentsArray(assembler, (kWordSize * 5)); |
| 676 | 675 |
| 677 // Stack: | 676 // Stack: |
| 678 // TOS + 0: Argument array. | 677 // TOS + 0: Argument array. |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 921 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 920 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
| 922 } | 921 } |
| 923 | 922 |
| 924 // Done allocating and initializing the context. | 923 // Done allocating and initializing the context. |
| 925 // RAX: new object. | 924 // RAX: new object. |
| 926 __ ret(); | 925 __ ret(); |
| 927 | 926 |
| 928 __ Bind(&slow_case); | 927 __ Bind(&slow_case); |
| 929 } | 928 } |
| 930 // Create a stub frame. | 929 // Create a stub frame. |
| 931 AssemblerMacros::EnterStubFrame(assembler); | 930 __ EnterStubFrame(); |
| 932 __ pushq(raw_null); // Setup space on stack for the return value. | 931 __ pushq(raw_null); // Setup space on stack for the return value. |
| 933 __ SmiTag(R10); | 932 __ SmiTag(R10); |
| 934 __ pushq(R10); // Push number of context variables. | 933 __ pushq(R10); // Push number of context variables. |
| 935 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. | 934 __ CallRuntime(kAllocateContextRuntimeEntry); // Allocate context. |
| 936 __ popq(RAX); // Pop number of context variables argument. | 935 __ popq(RAX); // Pop number of context variables argument. |
| 937 __ popq(RAX); // Pop the new context object. | 936 __ popq(RAX); // Pop the new context object. |
| 938 // RAX: new object | 937 // RAX: new object |
| 939 // Restore the frame pointer. | 938 // Restore the frame pointer. |
| 940 __ LeaveFrame(); | 939 __ LeaveFrame(); |
| 941 __ ret(); | 940 __ ret(); |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1140 __ addq(RAX, Immediate(kHeapObjectTag)); | 1139 __ addq(RAX, Immediate(kHeapObjectTag)); |
| 1141 __ ret(); | 1140 __ ret(); |
| 1142 | 1141 |
| 1143 __ Bind(&slow_case); | 1142 __ Bind(&slow_case); |
| 1144 } | 1143 } |
| 1145 if (is_cls_parameterized) { | 1144 if (is_cls_parameterized) { |
| 1146 __ movq(RAX, Address(RSP, kObjectTypeArgumentsOffset)); | 1145 __ movq(RAX, Address(RSP, kObjectTypeArgumentsOffset)); |
| 1147 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset)); | 1146 __ movq(RDX, Address(RSP, kInstantiatorTypeArgumentsOffset)); |
| 1148 } | 1147 } |
| 1149 // Create a stub frame. | 1148 // Create a stub frame. |
| 1150 AssemblerMacros::EnterStubFrame(assembler); | 1149 __ EnterStubFrame(); |
| 1151 __ pushq(raw_null); // Setup space on stack for return value. | 1150 __ pushq(raw_null); // Setup space on stack for return value. |
| 1152 __ PushObject(cls); // Push class of object to be allocated. | 1151 __ PushObject(cls); // Push class of object to be allocated. |
| 1153 if (is_cls_parameterized) { | 1152 if (is_cls_parameterized) { |
| 1154 __ pushq(RAX); // Push type arguments of object to be allocated. | 1153 __ pushq(RAX); // Push type arguments of object to be allocated. |
| 1155 __ pushq(RDX); // Push type arguments of instantiator. | 1154 __ pushq(RDX); // Push type arguments of instantiator. |
| 1156 } else { | 1155 } else { |
| 1157 __ pushq(raw_null); // Push null type arguments. | 1156 __ pushq(raw_null); // Push null type arguments. |
| 1158 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); | 1157 __ pushq(Immediate(Smi::RawValue(StubCode::kNoInstantiator))); |
| 1159 } | 1158 } |
| 1160 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. | 1159 __ CallRuntime(kAllocateObjectRuntimeEntry); // Allocate object. |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1282 | 1281 |
| 1283 __ Bind(&slow_case); | 1282 __ Bind(&slow_case); |
| 1284 } | 1283 } |
| 1285 if (has_type_arguments) { | 1284 if (has_type_arguments) { |
| 1286 __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); | 1285 __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); |
| 1287 } | 1286 } |
| 1288 if (is_implicit_instance_closure) { | 1287 if (is_implicit_instance_closure) { |
| 1289 __ movq(RAX, Address(RSP, kReceiverOffset)); | 1288 __ movq(RAX, Address(RSP, kReceiverOffset)); |
| 1290 } | 1289 } |
| 1291 // Create the stub frame. | 1290 // Create the stub frame. |
| 1292 AssemblerMacros::EnterStubFrame(assembler); | 1291 __ EnterStubFrame(); |
| 1293 __ pushq(raw_null); // Setup space on stack for the return value. | 1292 __ pushq(raw_null); // Setup space on stack for the return value. |
| 1294 __ PushObject(func); | 1293 __ PushObject(func); |
| 1295 if (is_implicit_static_closure) { | 1294 if (is_implicit_static_closure) { |
| 1296 __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry); | 1295 __ CallRuntime(kAllocateImplicitStaticClosureRuntimeEntry); |
| 1297 } else { | 1296 } else { |
| 1298 if (is_implicit_instance_closure) { | 1297 if (is_implicit_instance_closure) { |
| 1299 __ pushq(RAX); // Receiver. | 1298 __ pushq(RAX); // Receiver. |
| 1300 } | 1299 } |
| 1301 if (has_type_arguments) { | 1300 if (has_type_arguments) { |
| 1302 __ pushq(RCX); // Push type arguments of closure to be allocated. | 1301 __ pushq(RCX); // Push type arguments of closure to be allocated. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1334 // R10 : arguments descriptor array. | 1333 // R10 : arguments descriptor array. |
| 1335 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { | 1334 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { |
| 1336 // The target function was not found, so invoke method | 1335 // The target function was not found, so invoke method |
| 1337 // "dynamic noSuchMethod(InvocationMirror invocation)". | 1336 // "dynamic noSuchMethod(InvocationMirror invocation)". |
| 1338 const Immediate& raw_null = | 1337 const Immediate& raw_null = |
| 1339 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1338 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1340 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 1339 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 1341 __ movq(RAX, Address(RBP, R13, TIMES_4, kWordSize)); // Get receiver. | 1340 __ movq(RAX, Address(RBP, R13, TIMES_4, kWordSize)); // Get receiver. |
| 1342 | 1341 |
| 1343 // Create a stub frame. | 1342 // Create a stub frame. |
| 1344 AssemblerMacros::EnterStubFrame(assembler); | 1343 __ EnterStubFrame(); |
| 1345 | 1344 |
| 1346 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. | 1345 __ pushq(raw_null); // Setup space on stack for result from noSuchMethod. |
| 1347 __ pushq(RAX); // Receiver. | 1346 __ pushq(RAX); // Receiver. |
| 1348 __ pushq(RBX); // IC data array. | 1347 __ pushq(RBX); // IC data array. |
| 1349 __ pushq(R10); // Arguments descriptor array. | 1348 __ pushq(R10); // Arguments descriptor array. |
| 1350 | 1349 |
| 1351 __ movq(R10, R13); // Smi-tagged arguments array length. | 1350 __ movq(R10, R13); // Smi-tagged arguments array length. |
| 1352 // See stack layout below explaining "wordSize * 10" offset. | 1351 // See stack layout below explaining "wordSize * 10" offset. |
| 1353 PushArgumentsArray(assembler, (kWordSize * 10)); | 1352 PushArgumentsArray(assembler, (kWordSize * 10)); |
| 1354 | 1353 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1378 __ LeaveFrame(); | 1377 __ LeaveFrame(); |
| 1379 __ ret(); | 1378 __ ret(); |
| 1380 } | 1379 } |
| 1381 | 1380 |
| 1382 | 1381 |
| 1383 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { | 1382 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { |
| 1384 Register argdesc_reg = R10; | 1383 Register argdesc_reg = R10; |
| 1385 Register ic_reg = RBX; | 1384 Register ic_reg = RBX; |
| 1386 Register func_reg = RDI; | 1385 Register func_reg = RDI; |
| 1387 if (FLAG_trace_optimized_ic_calls) { | 1386 if (FLAG_trace_optimized_ic_calls) { |
| 1388 AssemblerMacros::EnterStubFrame(assembler); | 1387 __ EnterStubFrame(); |
| 1389 __ pushq(func_reg); // Preserve | 1388 __ pushq(func_reg); // Preserve |
| 1390 __ pushq(argdesc_reg); // Preserve. | 1389 __ pushq(argdesc_reg); // Preserve. |
| 1391 __ pushq(ic_reg); // Preserve. | 1390 __ pushq(ic_reg); // Preserve. |
| 1392 __ pushq(ic_reg); // Argument. | 1391 __ pushq(ic_reg); // Argument. |
| 1393 __ pushq(func_reg); // Argument. | 1392 __ pushq(func_reg); // Argument. |
| 1394 __ CallRuntime(kTraceICCallRuntimeEntry); | 1393 __ CallRuntime(kTraceICCallRuntimeEntry); |
| 1395 __ popq(RAX); // Discard argument; | 1394 __ popq(RAX); // Discard argument; |
| 1396 __ popq(RAX); // Discard argument; | 1395 __ popq(RAX); // Discard argument; |
| 1397 __ popq(ic_reg); // Restore. | 1396 __ popq(ic_reg); // Restore. |
| 1398 __ popq(argdesc_reg); // Restore. | 1397 __ popq(argdesc_reg); // Restore. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1515 __ cmpq(R13, Immediate(Smi::RawValue(kIllegalCid))); // Done? | 1514 __ cmpq(R13, Immediate(Smi::RawValue(kIllegalCid))); // Done? |
| 1516 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 1515 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
| 1517 | 1516 |
| 1518 // IC miss. | 1517 // IC miss. |
| 1519 const Immediate& raw_null = | 1518 const Immediate& raw_null = |
| 1520 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1519 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1521 // Compute address of arguments (first read number of arguments from | 1520 // Compute address of arguments (first read number of arguments from |
| 1522 // arguments descriptor array and then compute address on the stack). | 1521 // arguments descriptor array and then compute address on the stack). |
| 1523 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); | 1522 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); |
| 1524 __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX is Smi. | 1523 __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX is Smi. |
| 1525 AssemblerMacros::EnterStubFrame(assembler); | 1524 __ EnterStubFrame(); |
| 1526 __ pushq(R10); // Preserve arguments descriptor array. | 1525 __ pushq(R10); // Preserve arguments descriptor array. |
| 1527 __ pushq(RBX); // Preserve IC data object. | 1526 __ pushq(RBX); // Preserve IC data object. |
| 1528 __ pushq(raw_null); // Setup space on stack for result (target code object). | 1527 __ pushq(raw_null); // Setup space on stack for result (target code object). |
| 1529 // Push call arguments. | 1528 // Push call arguments. |
| 1530 for (intptr_t i = 0; i < num_args; i++) { | 1529 for (intptr_t i = 0; i < num_args; i++) { |
| 1531 __ movq(RCX, Address(RAX, -kWordSize * i)); | 1530 __ movq(RCX, Address(RAX, -kWordSize * i)); |
| 1532 __ pushq(RCX); | 1531 __ pushq(RCX); |
| 1533 } | 1532 } |
| 1534 __ pushq(RBX); // Pass IC data object. | 1533 __ pushq(RBX); // Pass IC data object. |
| 1535 __ pushq(R10); // Pass arguments descriptor array. | 1534 __ pushq(R10); // Pass arguments descriptor array. |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1663 // that does not check/count function invocations. | 1662 // that does not check/count function invocations. |
| 1664 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { | 1663 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { |
| 1665 GenerateNArgsCheckInlineCacheStub(assembler, 1); | 1664 GenerateNArgsCheckInlineCacheStub(assembler, 1); |
| 1666 } | 1665 } |
| 1667 | 1666 |
| 1668 // R10: Arguments descriptor array. | 1667 // R10: Arguments descriptor array. |
| 1669 // TOS(0): return address (Dart code). | 1668 // TOS(0): return address (Dart code). |
| 1670 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | 1669 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
| 1671 const Immediate& raw_null = | 1670 const Immediate& raw_null = |
| 1672 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1671 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1673 AssemblerMacros::EnterStubFrame(assembler); | 1672 __ EnterStubFrame(); |
| 1674 __ pushq(R10); // Preserve arguments descriptor. | 1673 __ pushq(R10); // Preserve arguments descriptor. |
| 1675 __ pushq(raw_null); // Room for result. | 1674 __ pushq(raw_null); // Room for result. |
| 1676 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); | 1675 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); |
| 1677 __ popq(RAX); // Code object. | 1676 __ popq(RAX); // Code object. |
| 1678 __ popq(R10); // Restore arguments descriptor. | 1677 __ popq(R10); // Restore arguments descriptor. |
| 1679 __ LeaveFrame(); | 1678 __ LeaveFrame(); |
| 1680 | 1679 |
| 1681 // Now call the static function. The breakpoint handler function | 1680 // Now call the static function. The breakpoint handler function |
| 1682 // ensures that the call target is compiled. | 1681 // ensures that the call target is compiled. |
| 1683 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); | 1682 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); |
| 1684 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1683 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 1685 __ jmp(RBX); | 1684 __ jmp(RBX); |
| 1686 } | 1685 } |
| 1687 | 1686 |
| 1688 | 1687 |
| 1689 // TOS(0): return address (Dart code). | 1688 // TOS(0): return address (Dart code). |
| 1690 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { | 1689 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { |
| 1691 AssemblerMacros::EnterStubFrame(assembler); | 1690 __ EnterStubFrame(); |
| 1692 __ pushq(RAX); | 1691 __ pushq(RAX); |
| 1693 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); | 1692 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); |
| 1694 __ popq(RAX); | 1693 __ popq(RAX); |
| 1695 __ LeaveFrame(); | 1694 __ LeaveFrame(); |
| 1696 | 1695 |
| 1697 __ popq(R11); // discard return address of call to this stub. | 1696 __ popq(R11); // discard return address of call to this stub. |
| 1698 __ LeaveFrame(); | 1697 __ LeaveFrame(); |
| 1699 __ ret(); | 1698 __ ret(); |
| 1700 } | 1699 } |
| 1701 | 1700 |
| 1702 | 1701 |
| 1703 // RBX: Inline cache data array. | 1702 // RBX: Inline cache data array. |
| 1704 // R10: Arguments descriptor array. | 1703 // R10: Arguments descriptor array. |
| 1705 // TOS(0): return address (Dart code). | 1704 // TOS(0): return address (Dart code). |
| 1706 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { | 1705 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { |
| 1707 AssemblerMacros::EnterStubFrame(assembler); | 1706 __ EnterStubFrame(); |
| 1708 __ pushq(RBX); | 1707 __ pushq(RBX); |
| 1709 __ pushq(R10); | 1708 __ pushq(R10); |
| 1710 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); | 1709 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); |
| 1711 __ popq(R10); | 1710 __ popq(R10); |
| 1712 __ popq(RBX); | 1711 __ popq(RBX); |
| 1713 __ LeaveFrame(); | 1712 __ LeaveFrame(); |
| 1714 | 1713 |
| 1715 // Find out which dispatch stub to call. | 1714 // Find out which dispatch stub to call. |
| 1716 Label test_two, test_three, test_four; | 1715 Label test_two, test_three, test_four; |
| 1717 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset())); | 1716 __ movq(RCX, FieldAddress(RBX, ICData::num_args_tested_offset())); |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1963 __ Bind(¬_smi); | 1962 __ Bind(¬_smi); |
| 1964 __ LoadClassId(RAX, RAX); | 1963 __ LoadClassId(RAX, RAX); |
| 1965 __ SmiTag(RAX); | 1964 __ SmiTag(RAX); |
| 1966 __ ret(); | 1965 __ ret(); |
| 1967 | 1966 |
| 1968 __ Bind(&update_ic_data); | 1967 __ Bind(&update_ic_data); |
| 1969 | 1968 |
| 1970 // RCX: ICData | 1969 // RCX: ICData |
| 1971 __ movq(RAX, Address(RSP, 1 * kWordSize)); | 1970 __ movq(RAX, Address(RSP, 1 * kWordSize)); |
| 1972 __ movq(R13, Address(RSP, 2 * kWordSize)); | 1971 __ movq(R13, Address(RSP, 2 * kWordSize)); |
| 1973 AssemblerMacros::EnterStubFrame(assembler); | 1972 __ EnterStubFrame(); |
| 1974 __ pushq(R13); // arg 0 | 1973 __ pushq(R13); // arg 0 |
| 1975 __ pushq(RAX); // arg 1 | 1974 __ pushq(RAX); // arg 1 |
| 1976 __ PushObject(Symbols::EqualOperator()); // Target's name. | 1975 __ PushObject(Symbols::EqualOperator()); // Target's name. |
| 1977 __ pushq(RBX); // ICData | 1976 __ pushq(RBX); // ICData |
| 1978 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry); | 1977 __ CallRuntime(kUpdateICDataTwoArgsRuntimeEntry); |
| 1979 __ Drop(4); | 1978 __ Drop(4); |
| 1980 __ LeaveFrame(); | 1979 __ LeaveFrame(); |
| 1981 | 1980 |
| 1982 __ jmp(&compute_result, Assembler::kNearJump); | 1981 __ jmp(&compute_result, Assembler::kNearJump); |
| 1983 } | 1982 } |
| 1984 | 1983 |
| 1985 // Calls to the runtime to optimize the given function. | 1984 // Calls to the runtime to optimize the given function. |
| 1986 // RDI: function to be reoptimized. | 1985 // RDI: function to be reoptimized. |
| 1987 // R10: argument descriptor (preserved). | 1986 // R10: argument descriptor (preserved). |
| 1988 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 1987 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
| 1989 const Immediate& raw_null = | 1988 const Immediate& raw_null = |
| 1990 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1989 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1991 AssemblerMacros::EnterStubFrame(assembler); | 1990 __ EnterStubFrame(); |
| 1992 __ pushq(R10); | 1991 __ pushq(R10); |
| 1993 __ pushq(raw_null); // Setup space on stack for return value. | 1992 __ pushq(raw_null); // Setup space on stack for return value. |
| 1994 __ pushq(RDI); | 1993 __ pushq(RDI); |
| 1995 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); | 1994 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry); |
| 1996 __ popq(RAX); // Disard argument. | 1995 __ popq(RAX); // Disard argument. |
| 1997 __ popq(RAX); // Get Code object. | 1996 __ popq(RAX); // Get Code object. |
| 1998 __ popq(R10); // Restore argument descriptor. | 1997 __ popq(R10); // Restore argument descriptor. |
| 1999 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); | 1998 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); |
| 2000 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1999 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| 2001 __ LeaveFrame(); | 2000 __ LeaveFrame(); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2075 __ cmpq(left, right); | 2074 __ cmpq(left, right); |
| 2076 __ Bind(&done); | 2075 __ Bind(&done); |
| 2077 __ popq(right); | 2076 __ popq(right); |
| 2078 __ popq(left); | 2077 __ popq(left); |
| 2079 __ ret(); | 2078 __ ret(); |
| 2080 } | 2079 } |
| 2081 | 2080 |
| 2082 } // namespace dart | 2081 } // namespace dart |
| 2083 | 2082 |
| 2084 #endif // defined TARGET_ARCH_X64 | 2083 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |