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

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

Issue 23454032: - Tighten assertions in the X64 assembler related to object pool usage. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 months 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
« no previous file with comments | « runtime/vm/intrinsifier_x64.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) 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/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments. 76 __ movq(Address(RSP, retval_offset), RAX); // Set retval in NativeArguments.
77 __ call(RBX); 77 __ call(RBX);
78 78
79 // Reset exit frame information in Isolate structure. 79 // Reset exit frame information in Isolate structure.
80 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); 80 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
81 81
82 // Load Context pointer from Isolate structure into RBX. 82 // Load Context pointer from Isolate structure into RBX.
83 __ movq(RBX, Address(CTX, Isolate::top_context_offset())); 83 __ movq(RBX, Address(CTX, Isolate::top_context_offset()));
84 84
85 // Reset Context pointer in Isolate structure. 85 // Reset Context pointer in Isolate structure.
86 __ LoadObject(R12, Object::Handle(), PP); 86 __ LoadObject(R12, Object::null_object(), PP);
87 __ movq(Address(CTX, Isolate::top_context_offset()), R12); 87 __ movq(Address(CTX, Isolate::top_context_offset()), R12);
88 88
89 // Cache Context pointer into CTX while executing Dart code. 89 // Cache Context pointer into CTX while executing Dart code.
90 __ movq(CTX, RBX); 90 __ movq(CTX, RBX);
91 91
92 __ LeaveFrame(); 92 __ LeaveFrame();
93 __ ret(); 93 __ ret();
94 } 94 }
95 95
96 96
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 __ movq(RSI, RBX); // Pass pointer to function entrypoint. 164 __ movq(RSI, RBX); // Pass pointer to function entrypoint.
165 __ call(&NativeEntry::NativeCallWrapperLabel()); 165 __ call(&NativeEntry::NativeCallWrapperLabel());
166 166
167 // Reset exit frame information in Isolate structure. 167 // Reset exit frame information in Isolate structure.
168 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); 168 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
169 169
170 // Load Context pointer from Isolate structure into R8. 170 // Load Context pointer from Isolate structure into R8.
171 __ movq(R8, Address(CTX, Isolate::top_context_offset())); 171 __ movq(R8, Address(CTX, Isolate::top_context_offset()));
172 172
173 // Reset Context pointer in Isolate structure. 173 // Reset Context pointer in Isolate structure.
174 __ LoadObject(R12, Object::Handle(), PP); 174 __ LoadObject(R12, Object::null_object(), PP);
175 __ movq(Address(CTX, Isolate::top_context_offset()), R12); 175 __ movq(Address(CTX, Isolate::top_context_offset()), R12);
176 176
177 // Cache Context pointer into CTX while executing Dart code. 177 // Cache Context pointer into CTX while executing Dart code.
178 __ movq(CTX, R8); 178 __ movq(CTX, R8);
179 179
180 __ LeaveFrame(); 180 __ LeaveFrame();
181 __ ret(); 181 __ ret();
182 } 182 }
183 183
184 184
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 __ movq(RDI, RSP); // Pass the pointer to the NativeArguments. 231 __ movq(RDI, RSP); // Pass the pointer to the NativeArguments.
232 __ call(RBX); 232 __ call(RBX);
233 233
234 // Reset exit frame information in Isolate structure. 234 // Reset exit frame information in Isolate structure.
235 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0)); 235 __ movq(Address(CTX, Isolate::top_exit_frame_info_offset()), Immediate(0));
236 236
237 // Load Context pointer from Isolate structure into R8. 237 // Load Context pointer from Isolate structure into R8.
238 __ movq(R8, Address(CTX, Isolate::top_context_offset())); 238 __ movq(R8, Address(CTX, Isolate::top_context_offset()));
239 239
240 // Reset Context pointer in Isolate structure. 240 // Reset Context pointer in Isolate structure.
241 __ LoadObject(R12, Object::Handle(), PP); 241 __ LoadObject(R12, Object::null_object(), PP);
242 __ movq(Address(CTX, Isolate::top_context_offset()), R12); 242 __ movq(Address(CTX, Isolate::top_context_offset()), R12);
243 243
244 // Cache Context pointer into CTX while executing Dart code. 244 // Cache Context pointer into CTX while executing Dart code.
245 __ movq(CTX, R8); 245 __ movq(CTX, R8);
246 246
247 __ LeaveFrame(); 247 __ LeaveFrame();
248 __ ret(); 248 __ ret();
249 } 249 }
250 250
251 251
252 // Input parameters: 252 // Input parameters:
253 // R10: arguments descriptor array. 253 // R10: arguments descriptor array.
254 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { 254 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
255 __ EnterStubFrame(); 255 __ EnterStubFrame();
256 __ pushq(R10); // Preserve arguments descriptor array. 256 __ pushq(R10); // Preserve arguments descriptor array.
257 // Setup space on stack for return value. 257 // Setup space on stack for return value.
258 __ PushObject(Object::Handle()); 258 __ PushObject(Object::null_object());
259 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); 259 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
260 __ popq(RAX); // Get Code object result. 260 __ popq(RAX); // Get Code object result.
261 __ popq(R10); // Restore arguments descriptor array. 261 __ popq(R10); // Restore arguments descriptor array.
262 // Remove the stub frame as we are about to jump to the dart function. 262 // Remove the stub frame as we are about to jump to the dart function.
263 __ LeaveFrame(); 263 __ LeaveFrame();
264 264
265 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset())); 265 __ movq(RBX, FieldAddress(RAX, Code::instructions_offset()));
266 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 266 __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
267 __ jmp(RBX); 267 __ jmp(RBX);
268 } 268 }
269 269
270 270
271 // Called from a static call only when an invalid code has been entered 271 // Called from a static call only when an invalid code has been entered
272 // (invalid because its function was optimized or deoptimized). 272 // (invalid because its function was optimized or deoptimized).
273 // R10: arguments descriptor array. 273 // R10: arguments descriptor array.
274 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { 274 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
275 __ EnterStubFrame(); 275 __ EnterStubFrame();
276 __ pushq(R10); // Preserve arguments descriptor array. 276 __ pushq(R10); // Preserve arguments descriptor array.
277 // Setup space on stack for return value. 277 // Setup space on stack for return value.
278 __ PushObject(Object::Handle()); 278 __ PushObject(Object::null_object());
279 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); 279 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
280 __ popq(RAX); // Get Code object. 280 __ popq(RAX); // Get Code object.
281 __ popq(R10); // Restore arguments descriptor array. 281 __ popq(R10); // Restore arguments descriptor array.
282 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); 282 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
283 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 283 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
284 __ LeaveFrame(); 284 __ LeaveFrame();
285 __ jmp(RAX); 285 __ jmp(RAX);
286 __ int3(); 286 __ int3();
287 } 287 }
288 288
289 289
290 // Input parameters: 290 // Input parameters:
291 // R10: smi-tagged argument count, may be zero. 291 // R10: smi-tagged argument count, may be zero.
292 // RBP[kParamEndSlotFromFp + 1]: last argument. 292 // RBP[kParamEndSlotFromFp + 1]: last argument.
293 static void PushArgumentsArray(Assembler* assembler) { 293 static void PushArgumentsArray(Assembler* assembler) {
294 __ LoadObject(R12, Object::Handle(), PP); 294 __ LoadObject(R12, Object::null_object(), PP);
295 // Allocate array to store arguments of caller. 295 // Allocate array to store arguments of caller.
296 __ movq(RBX, R12); // Null element type for raw Array. 296 __ movq(RBX, R12); // Null element type for raw Array.
297 __ call(&StubCode::AllocateArrayLabel()); 297 __ call(&StubCode::AllocateArrayLabel());
298 __ SmiUntag(R10); 298 __ SmiUntag(R10);
299 // RAX: newly allocated array. 299 // RAX: newly allocated array.
300 // R10: length of the array (was preserved by the stub). 300 // R10: length of the array (was preserved by the stub).
301 __ pushq(RAX); // Array is in RAX and on top of stack. 301 __ pushq(RAX); // Array is in RAX and on top of stack.
302 __ leaq(R12, Address(RBP, R10, TIMES_8, kParamEndSlotFromFp * kWordSize)); 302 __ leaq(R12, Address(RBP, R10, TIMES_8, kParamEndSlotFromFp * kWordSize));
303 __ leaq(RBX, FieldAddress(RAX, Array::data_offset())); 303 __ leaq(RBX, FieldAddress(RAX, Array::data_offset()));
304 // R12: address of first argument on stack. 304 // R12: address of first argument on stack.
(...skipping 12 matching lines...) Expand all
317 317
318 318
319 // Input parameters: 319 // Input parameters:
320 // RBX: ic-data. 320 // RBX: ic-data.
321 // R10: arguments descriptor array. 321 // R10: arguments descriptor array.
322 // Note: The receiver object is the first argument to the function being 322 // Note: The receiver object is the first argument to the function being
323 // called, the stub accesses the receiver from this location directly 323 // called, the stub accesses the receiver from this location directly
324 // when trying to resolve the call. 324 // when trying to resolve the call.
325 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { 325 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) {
326 __ EnterStubFrameWithPP(); 326 __ EnterStubFrameWithPP();
327 __ PushObject(Object::Handle()); // Space for the return value. 327 __ PushObject(Object::null_object()); // Space for the return value.
328 328
329 // Push the receiver as an argument. Load the smi-tagged argument 329 // Push the receiver as an argument. Load the smi-tagged argument
330 // count into R13 to index the receiver in the stack. There are 330 // count into R13 to index the receiver in the stack. There are
331 // four words (null, stub's pc marker, saved pp, saved fp) above the return 331 // four words (null, stub's pc marker, saved pp, saved fp) above the return
332 // address. 332 // address.
333 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 333 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
334 __ pushq(Address(RSP, R13, TIMES_4, (4 * kWordSize))); 334 __ pushq(Address(RSP, R13, TIMES_4, (4 * kWordSize)));
335 335
336 __ pushq(RBX); // Pass IC data object. 336 __ pushq(RBX); // Pass IC data object.
337 __ pushq(R10); // Pass arguments descriptor array. 337 __ pushq(R10); // Pass arguments descriptor array.
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 497 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
498 // Three words (saved pp, saved fp, stub's pc marker) 498 // Three words (saved pp, saved fp, stub's pc marker)
499 // in the stack above the return address. 499 // in the stack above the return address.
500 __ movq(RAX, Address(RSP, RAX, TIMES_4, 500 __ movq(RAX, Address(RSP, RAX, TIMES_4,
501 kSavedAboveReturnAddress * kWordSize)); 501 kSavedAboveReturnAddress * kWordSize));
502 // Preserve IC data and arguments descriptor. 502 // Preserve IC data and arguments descriptor.
503 __ pushq(RBX); 503 __ pushq(RBX);
504 __ pushq(R10); 504 __ pushq(R10);
505 505
506 // Space for the result of the runtime call. 506 // Space for the result of the runtime call.
507 __ PushObject(Object::Handle()); 507 __ PushObject(Object::null_object());
508 __ pushq(RAX); // Receiver. 508 __ pushq(RAX); // Receiver.
509 __ pushq(RBX); // IC data. 509 __ pushq(RBX); // IC data.
510 __ pushq(R10); // Arguments descriptor. 510 __ pushq(R10); // Arguments descriptor.
511 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); 511 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3);
512 // Discard arguments. 512 // Discard arguments.
513 __ popq(RAX); 513 __ popq(RAX);
514 __ popq(RAX); 514 __ popq(RAX);
515 __ popq(RAX); 515 __ popq(RAX);
516 __ popq(RAX); // Return value from the runtime call (instructions). 516 __ popq(RAX); // Return value from the runtime call (instructions).
517 __ popq(R10); // Restore arguments descriptor. 517 __ popq(R10); // Restore arguments descriptor.
518 __ popq(RBX); // Restore IC data. 518 __ popq(RBX); // Restore IC data.
519 __ LeaveFrameWithPP(); 519 __ LeaveFrameWithPP();
520 520
521 Label lookup; 521 Label lookup;
522 __ CompareObject(RAX, Object::Handle()); 522 __ CompareObject(RAX, Object::null_object());
523 __ j(EQUAL, &lookup, Assembler::kNearJump); 523 __ j(EQUAL, &lookup, Assembler::kNearJump);
524 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 524 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
525 __ jmp(RAX); 525 __ jmp(RAX);
526 526
527 __ Bind(&lookup); 527 __ Bind(&lookup);
528 __ jmp(&StubCode::InstanceFunctionLookupLabel()); 528 __ jmp(&StubCode::InstanceFunctionLookupLabel());
529 } 529 }
530 530
531 531
532 // Called for inline allocation of arrays. 532 // Called for inline allocation of arrays.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 __ movq(FieldAddress(RAX, Array::tags_offset()), RBX); 618 __ movq(FieldAddress(RAX, Array::tags_offset()), RBX);
619 } 619 }
620 620
621 // Initialize all array elements to raw_null. 621 // Initialize all array elements to raw_null.
622 // RAX: new object start as a tagged pointer. 622 // RAX: new object start as a tagged pointer.
623 // R12: new object end address. 623 // R12: new object end address.
624 // R10: Array length as Smi. 624 // R10: Array length as Smi.
625 __ leaq(RBX, FieldAddress(RAX, Array::data_offset())); 625 __ leaq(RBX, FieldAddress(RAX, Array::data_offset()));
626 // RBX: iterator which initially points to the start of the variable 626 // RBX: iterator which initially points to the start of the variable
627 // data area to be initialized. 627 // data area to be initialized.
628 __ LoadObject(R13, Object::Handle(), PP); 628 __ LoadObject(R13, Object::null_object(), PP);
629 Label done; 629 Label done;
630 Label init_loop; 630 Label init_loop;
631 __ Bind(&init_loop); 631 __ Bind(&init_loop);
632 __ cmpq(RBX, R12); 632 __ cmpq(RBX, R12);
633 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); 633 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
634 // TODO(cshapiro): StoreIntoObjectNoBarrier 634 // TODO(cshapiro): StoreIntoObjectNoBarrier
635 __ movq(Address(RBX, 0), R13); 635 __ movq(Address(RBX, 0), R13);
636 __ addq(RBX, Immediate(kWordSize)); 636 __ addq(RBX, Immediate(kWordSize));
637 __ jmp(&init_loop, Assembler::kNearJump); 637 __ jmp(&init_loop, Assembler::kNearJump);
638 __ Bind(&done); 638 __ Bind(&done);
639 639
640 // Done allocating and initializing the array. 640 // Done allocating and initializing the array.
641 // RAX: new object. 641 // RAX: new object.
642 // R10: Array length as Smi (preserved for the caller.) 642 // R10: Array length as Smi (preserved for the caller.)
643 __ ret(); 643 __ ret();
644 } 644 }
645 645
646 // Unable to allocate the array using the fast inline code, just call 646 // Unable to allocate the array using the fast inline code, just call
647 // into the runtime. 647 // into the runtime.
648 __ Bind(&slow_case); 648 __ Bind(&slow_case);
649 // Create a stub frame as we are pushing some objects on the stack before 649 // Create a stub frame as we are pushing some objects on the stack before
650 // calling into the runtime. 650 // calling into the runtime.
651 __ EnterStubFrame(); 651 __ EnterStubFrame();
652 // Setup space on stack for return value. 652 // Setup space on stack for return value.
653 __ PushObject(Object::Handle()); 653 __ PushObject(Object::null_object());
654 __ pushq(R10); // Array length as Smi. 654 __ pushq(R10); // Array length as Smi.
655 __ pushq(RBX); // Element type. 655 __ pushq(RBX); // Element type.
656 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); 656 __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
657 __ popq(RAX); // Pop element type argument. 657 __ popq(RAX); // Pop element type argument.
658 __ popq(R10); // Pop array length argument. 658 __ popq(R10); // Pop array length argument.
659 __ popq(RAX); // Pop return value from return slot. 659 __ popq(RAX); // Pop return value from return slot.
660 __ LeaveFrame(); 660 __ LeaveFrame();
661 __ ret(); 661 __ ret();
662 } 662 }
663 663
664 664
665 // Input parameters: 665 // Input parameters:
666 // R10: Arguments descriptor array. 666 // R10: Arguments descriptor array.
667 // Note: The closure object is the first argument to the function being 667 // Note: The closure object is the first argument to the function being
668 // called, the stub accesses the closure from this location directly 668 // called, the stub accesses the closure from this location directly
669 // when trying to resolve the call. 669 // when trying to resolve the call.
670 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) { 670 void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) {
671 // Load num_args. 671 // Load num_args.
672 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 672 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
673 // Load closure object in R13. 673 // Load closure object in R13.
674 __ movq(R13, Address(RSP, RAX, TIMES_4, 0)); // RAX is a Smi. 674 __ movq(R13, Address(RSP, RAX, TIMES_4, 0)); // RAX is a Smi.
675 675
676 __ LoadObject(R12, Object::Handle(), PP); 676 __ LoadObject(R12, Object::null_object(), PP);
677 677
678 // Verify that R13 is a closure by checking its class. 678 // Verify that R13 is a closure by checking its class.
679 Label not_closure; 679 Label not_closure;
680 __ cmpq(R13, R12); 680 __ cmpq(R13, R12);
681 // Not a closure, but null object. 681 // Not a closure, but null object.
682 __ j(EQUAL, &not_closure); 682 __ j(EQUAL, &not_closure);
683 __ testq(R13, Immediate(kSmiTagMask)); 683 __ testq(R13, Immediate(kSmiTagMask));
684 __ j(ZERO, &not_closure); // Not a closure, but a smi. 684 __ j(ZERO, &not_closure); // Not a closure, but a smi.
685 // Verify that the class of the object is a closure class by checking that 685 // Verify that the class of the object is a closure class by checking that
686 // class.signature_function() is not null. 686 // class.signature_function() is not null.
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
878 __ ret(); 878 __ ret();
879 } 879 }
880 880
881 881
882 // Called for inline allocation of contexts. 882 // Called for inline allocation of contexts.
883 // Input: 883 // Input:
884 // R10: number of context variables. 884 // R10: number of context variables.
885 // Output: 885 // Output:
886 // RAX: new allocated RawContext object. 886 // RAX: new allocated RawContext object.
887 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { 887 void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
888 __ LoadObject(R12, Object::Handle(), PP); 888 __ LoadObject(R12, Object::null_object(), PP);
889 if (FLAG_inline_alloc) { 889 if (FLAG_inline_alloc) {
890 const Class& context_class = Class::ZoneHandle(Object::context_class()); 890 const Class& context_class = Class::ZoneHandle(Object::context_class());
891 Label slow_case; 891 Label slow_case;
892 Heap* heap = Isolate::Current()->heap(); 892 Heap* heap = Isolate::Current()->heap();
893 // First compute the rounded instance size. 893 // First compute the rounded instance size.
894 // R10: number of context variables. 894 // R10: number of context variables.
895 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); 895 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1);
896 __ leaq(R13, Address(R10, TIMES_8, fixed_size)); 896 __ leaq(R13, Address(R10, TIMES_8, fixed_size));
897 __ andq(R13, Immediate(-kObjectAlignment)); 897 __ andq(R13, Immediate(-kObjectAlignment));
898 898
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 const bool is_cls_parameterized = cls.HasTypeArguments(); 1077 const bool is_cls_parameterized = cls.HasTypeArguments();
1078 ASSERT(!cls.HasTypeArguments() || 1078 ASSERT(!cls.HasTypeArguments() ||
1079 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); 1079 (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
1080 // kInlineInstanceSize is a constant used as a threshold for determining 1080 // kInlineInstanceSize is a constant used as a threshold for determining
1081 // when the object initialization should be done as a loop or as 1081 // when the object initialization should be done as a loop or as
1082 // straight line code. 1082 // straight line code.
1083 const int kInlineInstanceSize = 12; // In words. 1083 const int kInlineInstanceSize = 12; // In words.
1084 const intptr_t instance_size = cls.instance_size(); 1084 const intptr_t instance_size = cls.instance_size();
1085 ASSERT(instance_size > 0); 1085 ASSERT(instance_size > 0);
1086 const intptr_t type_args_size = InstantiatedTypeArguments::InstanceSize(); 1086 const intptr_t type_args_size = InstantiatedTypeArguments::InstanceSize();
1087 __ LoadObject(R12, Object::Handle(), PP); 1087 __ LoadObject(R12, Object::null_object(), PP);
1088 if (FLAG_inline_alloc && 1088 if (FLAG_inline_alloc &&
1089 Heap::IsAllocatableInNewSpace(instance_size + type_args_size)) { 1089 Heap::IsAllocatableInNewSpace(instance_size + type_args_size)) {
1090 Label slow_case; 1090 Label slow_case;
1091 Heap* heap = Isolate::Current()->heap(); 1091 Heap* heap = Isolate::Current()->heap();
1092 __ movq(RAX, Immediate(heap->TopAddress())); 1092 __ movq(RAX, Immediate(heap->TopAddress()));
1093 __ movq(RAX, Address(RAX, 0)); 1093 __ movq(RAX, Address(RAX, 0));
1094 __ leaq(RBX, Address(RAX, instance_size)); 1094 __ leaq(RBX, Address(RAX, instance_size));
1095 if (is_cls_parameterized) { 1095 if (is_cls_parameterized) {
1096 __ movq(RCX, RBX); 1096 __ movq(RCX, RBX);
1097 // A new InstantiatedTypeArguments object only needs to be allocated if 1097 // A new InstantiatedTypeArguments object only needs to be allocated if
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, 1244 void StubCode::GenerateAllocationStubForClosure(Assembler* assembler,
1245 const Function& func) { 1245 const Function& func) {
1246 ASSERT(func.IsClosureFunction()); 1246 ASSERT(func.IsClosureFunction());
1247 ASSERT(!func.IsImplicitStaticClosureFunction()); 1247 ASSERT(!func.IsImplicitStaticClosureFunction());
1248 const bool is_implicit_instance_closure = 1248 const bool is_implicit_instance_closure =
1249 func.IsImplicitInstanceClosureFunction(); 1249 func.IsImplicitInstanceClosureFunction();
1250 const Class& cls = Class::ZoneHandle(func.signature_class()); 1250 const Class& cls = Class::ZoneHandle(func.signature_class());
1251 const bool has_type_arguments = cls.HasTypeArguments(); 1251 const bool has_type_arguments = cls.HasTypeArguments();
1252 1252
1253 __ EnterStubFrameWithPP(); // Uses pool pointer to refer to function. 1253 __ EnterStubFrameWithPP(); // Uses pool pointer to refer to function.
1254 __ LoadObject(R12, Object::Handle(), PP); 1254 __ LoadObject(R12, Object::null_object(), PP);
1255 const intptr_t kTypeArgumentsOffset = 4 * kWordSize; 1255 const intptr_t kTypeArgumentsOffset = 4 * kWordSize;
1256 const intptr_t kReceiverOffset = 5 * kWordSize; 1256 const intptr_t kReceiverOffset = 5 * kWordSize;
1257 const intptr_t closure_size = Closure::InstanceSize(); 1257 const intptr_t closure_size = Closure::InstanceSize();
1258 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. 1258 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver.
1259 if (FLAG_inline_alloc && 1259 if (FLAG_inline_alloc &&
1260 Heap::IsAllocatableInNewSpace(closure_size + context_size)) { 1260 Heap::IsAllocatableInNewSpace(closure_size + context_size)) {
1261 Label slow_case; 1261 Label slow_case;
1262 Heap* heap = Isolate::Current()->heap(); 1262 Heap* heap = Isolate::Current()->heap();
1263 __ movq(RAX, Immediate(heap->TopAddress())); 1263 __ movq(RAX, Immediate(heap->TopAddress()));
1264 __ movq(RAX, Address(RAX, 0)); 1264 __ movq(RAX, Address(RAX, 0));
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1387 // RSP + 8 : address of last argument. 1387 // RSP + 8 : address of last argument.
1388 // RBX : ic-data. 1388 // RBX : ic-data.
1389 // R10 : arguments descriptor array. 1389 // R10 : arguments descriptor array.
1390 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) { 1390 void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
1391 __ EnterStubFrame(); 1391 __ EnterStubFrame();
1392 1392
1393 // Load the receiver. 1393 // Load the receiver.
1394 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 1394 __ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
1395 __ movq(RAX, Address(RBP, R13, TIMES_4, kParamEndSlotFromFp * kWordSize)); 1395 __ movq(RAX, Address(RBP, R13, TIMES_4, kParamEndSlotFromFp * kWordSize));
1396 1396
1397 __ LoadObject(R12, Object::Handle(), PP); 1397 __ LoadObject(R12, Object::null_object(), PP);
1398 __ pushq(R12); // Setup space on stack for result from noSuchMethod. 1398 __ pushq(R12); // Setup space on stack for result from noSuchMethod.
1399 __ pushq(RAX); // Receiver. 1399 __ pushq(RAX); // Receiver.
1400 __ pushq(RBX); // IC data array. 1400 __ pushq(RBX); // IC data array.
1401 __ pushq(R10); // Arguments descriptor array. 1401 __ pushq(R10); // Arguments descriptor array.
1402 1402
1403 __ movq(R10, R13); // Smi-tagged arguments array length. 1403 __ movq(R10, R13); // Smi-tagged arguments array length.
1404 PushArgumentsArray(assembler); 1404 PushArgumentsArray(assembler);
1405 1405
1406 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry, 4); 1406 __ CallRuntime(kInvokeNoSuchMethodFunctionRuntimeEntry, 4);
1407 1407
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1536 1536
1537 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; 1537 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
1538 __ addq(R12, Immediate(entry_size)); // Next entry. 1538 __ addq(R12, Immediate(entry_size)); // Next entry.
1539 __ movq(R13, Address(R12, 0)); // Next class ID. 1539 __ movq(R13, Address(R12, 0)); // Next class ID.
1540 1540
1541 __ Bind(&test); 1541 __ Bind(&test);
1542 __ cmpq(R13, Immediate(Smi::RawValue(kIllegalCid))); // Done? 1542 __ cmpq(R13, Immediate(Smi::RawValue(kIllegalCid))); // Done?
1543 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1543 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1544 1544
1545 // IC miss. 1545 // IC miss.
1546 __ LoadObject(R12, Object::Handle(), PP); 1546 __ LoadObject(R12, Object::null_object(), PP);
1547 // Compute address of arguments (first read number of arguments from 1547 // Compute address of arguments (first read number of arguments from
1548 // arguments descriptor array and then compute address on the stack). 1548 // arguments descriptor array and then compute address on the stack).
1549 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 1549 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
1550 __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX is Smi. 1550 __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX is Smi.
1551 __ EnterStubFrame(); 1551 __ EnterStubFrame();
1552 __ pushq(R10); // Preserve arguments descriptor array. 1552 __ pushq(R10); // Preserve arguments descriptor array.
1553 __ pushq(RBX); // Preserve IC data object. 1553 __ pushq(RBX); // Preserve IC data object.
1554 __ pushq(R12); // Setup space on stack for result (target code object). 1554 __ pushq(R12); // Setup space on stack for result (target code object).
1555 // Push call arguments. 1555 // Push call arguments.
1556 for (intptr_t i = 0; i < num_args; i++) { 1556 for (intptr_t i = 0; i < num_args; i++) {
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
1731 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1))); 1731 __ addq(Address(R12, count_offset), Immediate(Smi::RawValue(1)));
1732 __ j(NO_OVERFLOW, &increment_done, Assembler::kNearJump); 1732 __ j(NO_OVERFLOW, &increment_done, Assembler::kNearJump);
1733 __ movq(Address(R12, count_offset), 1733 __ movq(Address(R12, count_offset),
1734 Immediate(Smi::RawValue(Smi::kMaxValue))); 1734 Immediate(Smi::RawValue(Smi::kMaxValue)));
1735 __ Bind(&increment_done); 1735 __ Bind(&increment_done);
1736 1736
1737 Label target_is_compiled; 1737 Label target_is_compiled;
1738 // Get function and call it, if possible. 1738 // Get function and call it, if possible.
1739 __ movq(R13, Address(R12, target_offset)); 1739 __ movq(R13, Address(R12, target_offset));
1740 __ movq(RAX, FieldAddress(R13, Function::code_offset())); 1740 __ movq(RAX, FieldAddress(R13, Function::code_offset()));
1741 __ LoadObject(R12, Object::Handle(), PP); 1741 __ LoadObject(R12, Object::null_object(), PP);
1742 __ cmpq(RAX, R12); 1742 __ cmpq(RAX, R12);
1743 __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump); 1743 __ j(NOT_EQUAL, &target_is_compiled, Assembler::kNearJump);
1744 1744
1745 __ EnterStubFrame(); 1745 __ EnterStubFrame();
1746 __ pushq(R13); // Preserve target function. 1746 __ pushq(R13); // Preserve target function.
1747 __ pushq(RBX); // Preserve IC data object. 1747 __ pushq(RBX); // Preserve IC data object.
1748 __ pushq(R13); // Pass function. 1748 __ pushq(R13); // Pass function.
1749 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); 1749 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1750 __ popq(RAX); // Discard argument. 1750 __ popq(RAX); // Discard argument.
1751 __ popq(RBX); // Restore IC data object. 1751 __ popq(RBX); // Restore IC data object.
(...skipping 20 matching lines...) Expand all
1772 1772
1773 // RBX, R10: May contain arguments to runtime stub. 1773 // RBX, R10: May contain arguments to runtime stub.
1774 // TOS(0): return address (Dart code). 1774 // TOS(0): return address (Dart code).
1775 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) { 1775 void StubCode::GenerateBreakpointRuntimeStub(Assembler* assembler) {
1776 __ EnterStubFrame(); 1776 __ EnterStubFrame();
1777 // Preserve runtime args. 1777 // Preserve runtime args.
1778 __ pushq(RBX); 1778 __ pushq(RBX);
1779 __ pushq(R10); 1779 __ pushq(R10);
1780 // Room for result. Debugger stub returns address of the 1780 // Room for result. Debugger stub returns address of the
1781 // unpatched runtime stub. 1781 // unpatched runtime stub.
1782 __ LoadObject(R12, Object::Handle(), PP); 1782 __ LoadObject(R12, Object::null_object(), PP);
1783 __ pushq(R12); // Room for result. 1783 __ pushq(R12); // Room for result.
1784 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); 1784 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
1785 __ popq(RAX); // Address of original. 1785 __ popq(RAX); // Address of original.
1786 __ popq(R10); // Restore arguments. 1786 __ popq(R10); // Restore arguments.
1787 __ popq(RBX); 1787 __ popq(RBX);
1788 __ LeaveFrame(); 1788 __ LeaveFrame();
1789 __ jmp(RAX); // Jump to original stub. 1789 __ jmp(RAX); // Jump to original stub.
1790 } 1790 }
1791 1791
1792 1792
1793 // RBX: ICData (unoptimized static call) 1793 // RBX: ICData (unoptimized static call)
1794 // TOS(0): return address (Dart code). 1794 // TOS(0): return address (Dart code).
1795 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { 1795 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) {
1796 __ EnterStubFrame(); 1796 __ EnterStubFrame();
1797 __ LoadObject(R12, Object::Handle(), PP); 1797 __ LoadObject(R12, Object::null_object(), PP);
1798 __ pushq(RBX); // Preserve IC data for unoptimized call. 1798 __ pushq(RBX); // Preserve IC data for unoptimized call.
1799 __ pushq(R12); // Room for result. 1799 __ pushq(R12); // Room for result.
1800 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry, 0); 1800 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry, 0);
1801 __ popq(RAX); // Code object. 1801 __ popq(RAX); // Code object.
1802 __ popq(RBX); // Restore IC data. 1802 __ popq(RBX); // Restore IC data.
1803 __ LeaveFrame(); 1803 __ LeaveFrame();
1804 1804
1805 // Load arguments descriptor into R10. 1805 // Load arguments descriptor into R10.
1806 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); 1806 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
1807 // Now call the static function. The breakpoint handler function 1807 // Now call the static function. The breakpoint handler function
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 // TOS + 1: instantiator type arguments (can be NULL). 1859 // TOS + 1: instantiator type arguments (can be NULL).
1860 // TOS + 2: instance. 1860 // TOS + 2: instance.
1861 // TOS + 3: SubtypeTestCache. 1861 // TOS + 3: SubtypeTestCache.
1862 // Result in RCX: null -> not found, otherwise result (true or false). 1862 // Result in RCX: null -> not found, otherwise result (true or false).
1863 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { 1863 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
1864 ASSERT((1 <= n) && (n <= 3)); 1864 ASSERT((1 <= n) && (n <= 3));
1865 const intptr_t kInstantiatorTypeArgumentsInBytes = 1 * kWordSize; 1865 const intptr_t kInstantiatorTypeArgumentsInBytes = 1 * kWordSize;
1866 const intptr_t kInstanceOffsetInBytes = 2 * kWordSize; 1866 const intptr_t kInstanceOffsetInBytes = 2 * kWordSize;
1867 const intptr_t kCacheOffsetInBytes = 3 * kWordSize; 1867 const intptr_t kCacheOffsetInBytes = 3 * kWordSize;
1868 __ movq(RAX, Address(RSP, kInstanceOffsetInBytes)); 1868 __ movq(RAX, Address(RSP, kInstanceOffsetInBytes));
1869 __ LoadObject(R12, Object::Handle(), PP); 1869 __ LoadObject(R12, Object::null_object(), PP);
1870 if (n > 1) { 1870 if (n > 1) {
1871 __ LoadClass(R10, RAX); 1871 __ LoadClass(R10, RAX);
1872 // Compute instance type arguments into R13. 1872 // Compute instance type arguments into R13.
1873 Label has_no_type_arguments; 1873 Label has_no_type_arguments;
1874 __ movq(R13, R12); 1874 __ movq(R13, R12);
1875 __ movq(RDI, FieldAddress(R10, 1875 __ movq(RDI, FieldAddress(R10,
1876 Class::type_arguments_field_offset_in_words_offset())); 1876 Class::type_arguments_field_offset_in_words_offset()));
1877 __ cmpq(RDI, Immediate(Class::kNoTypeArguments)); 1877 __ cmpq(RDI, Immediate(Class::kNoTypeArguments));
1878 __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump); 1878 __ j(EQUAL, &has_no_type_arguments, Assembler::kNearJump);
1879 __ movq(R13, FieldAddress(RAX, RDI, TIMES_8, 0)); 1879 __ movq(R13, FieldAddress(RAX, RDI, TIMES_8, 0));
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
2087 __ LeaveFrame(); 2087 __ LeaveFrame();
2088 2088
2089 __ jmp(&compute_result, Assembler::kNearJump); 2089 __ jmp(&compute_result, Assembler::kNearJump);
2090 } 2090 }
2091 2091
2092 // Calls to the runtime to optimize the given function. 2092 // Calls to the runtime to optimize the given function.
2093 // RDI: function to be reoptimized. 2093 // RDI: function to be reoptimized.
2094 // R10: argument descriptor (preserved). 2094 // R10: argument descriptor (preserved).
2095 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { 2095 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
2096 __ EnterStubFrameWithPP(); 2096 __ EnterStubFrameWithPP();
2097 __ LoadObject(R12, Object::Handle(), PP); 2097 __ LoadObject(R12, Object::null_object(), PP);
2098 __ pushq(R10); 2098 __ pushq(R10);
2099 __ pushq(R12); // Setup space on stack for return value. 2099 __ pushq(R12); // Setup space on stack for return value.
2100 __ pushq(RDI); 2100 __ pushq(RDI);
2101 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); 2101 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
2102 __ popq(RAX); // Disard argument. 2102 __ popq(RAX); // Disard argument.
2103 __ popq(RAX); // Get Code object. 2103 __ popq(RAX); // Get Code object.
2104 __ popq(R10); // Restore argument descriptor. 2104 __ popq(R10); // Restore argument descriptor.
2105 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset())); 2105 __ movq(RAX, FieldAddress(RAX, Code::instructions_offset()));
2106 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 2106 __ addq(RAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
2107 __ LeaveFrameWithPP(); 2107 __ LeaveFrameWithPP();
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
2220 __ movq(right, Address(RSP, 3 * kWordSize)); 2220 __ movq(right, Address(RSP, 3 * kWordSize));
2221 GenerateIdenticalWithNumberCheckStub(assembler, left, right); 2221 GenerateIdenticalWithNumberCheckStub(assembler, left, right);
2222 __ popq(right); 2222 __ popq(right);
2223 __ popq(left); 2223 __ popq(left);
2224 __ ret(); 2224 __ ret();
2225 } 2225 }
2226 2226
2227 } // namespace dart 2227 } // namespace dart
2228 2228
2229 #endif // defined TARGET_ARCH_X64 2229 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698