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_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 | 309 |
310 // Input parameters: | 310 // Input parameters: |
311 // S4: arguments descriptor array. | 311 // S4: arguments descriptor array. |
312 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { | 312 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { |
313 __ Comment("CallStaticFunctionStub"); | 313 __ Comment("CallStaticFunctionStub"); |
314 __ EnterStubFrame(); | 314 __ EnterStubFrame(); |
315 // Setup space on stack for return value and preserve arguments descriptor. | 315 // Setup space on stack for return value and preserve arguments descriptor. |
316 | 316 |
317 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 317 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
318 __ sw(S4, Address(SP, 1 * kWordSize)); | 318 __ sw(S4, Address(SP, 1 * kWordSize)); |
319 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 319 __ LoadObject(TMP, Object::null_object()); |
320 __ sw(TMP, Address(SP, 0 * kWordSize)); | 320 __ sw(TMP, Address(SP, 0 * kWordSize)); |
321 | 321 |
322 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); | 322 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); |
323 __ Comment("CallStaticFunctionStub return"); | 323 __ Comment("CallStaticFunctionStub return"); |
324 | 324 |
325 // Get Code object result and restore arguments descriptor array. | 325 // Get Code object result and restore arguments descriptor array. |
326 __ lw(T0, Address(SP, 0 * kWordSize)); | 326 __ lw(T0, Address(SP, 0 * kWordSize)); |
327 __ lw(S4, Address(SP, 1 * kWordSize)); | 327 __ lw(S4, Address(SP, 1 * kWordSize)); |
328 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 328 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
329 | 329 |
330 __ lw(T0, FieldAddress(T0, Code::entry_point_offset())); | 330 __ lw(T0, FieldAddress(T0, Code::entry_point_offset())); |
331 | 331 |
332 // Remove the stub frame as we are about to jump to the dart function. | 332 // Remove the stub frame as we are about to jump to the dart function. |
333 __ LeaveStubFrameAndReturn(T0); | 333 __ LeaveStubFrameAndReturn(T0); |
334 } | 334 } |
335 | 335 |
336 | 336 |
337 // Called from a static call only when an invalid code has been entered | 337 // Called from a static call only when an invalid code has been entered |
338 // (invalid because its function was optimized or deoptimized). | 338 // (invalid because its function was optimized or deoptimized). |
339 // S4: arguments descriptor array. | 339 // S4: arguments descriptor array. |
340 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 340 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
341 // Create a stub frame as we are pushing some objects on the stack before | 341 // Create a stub frame as we are pushing some objects on the stack before |
342 // calling into the runtime. | 342 // calling into the runtime. |
343 __ Comment("FixCallersTarget"); | 343 __ Comment("FixCallersTarget"); |
344 __ EnterStubFrame(); | 344 __ EnterStubFrame(); |
345 // Setup space on stack for return value and preserve arguments descriptor. | 345 // Setup space on stack for return value and preserve arguments descriptor. |
346 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 346 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
347 __ sw(S4, Address(SP, 1 * kWordSize)); | 347 __ sw(S4, Address(SP, 1 * kWordSize)); |
348 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 348 __ LoadObject(TMP, Object::null_object()); |
349 __ sw(TMP, Address(SP, 0 * kWordSize)); | 349 __ sw(TMP, Address(SP, 0 * kWordSize)); |
350 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); | 350 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); |
351 // Get Code object result and restore arguments descriptor array. | 351 // Get Code object result and restore arguments descriptor array. |
352 __ lw(T0, Address(SP, 0 * kWordSize)); | 352 __ lw(T0, Address(SP, 0 * kWordSize)); |
353 __ lw(S4, Address(SP, 1 * kWordSize)); | 353 __ lw(S4, Address(SP, 1 * kWordSize)); |
354 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 354 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
355 | 355 |
356 // Jump to the dart function. | 356 // Jump to the dart function. |
357 __ lw(T0, FieldAddress(T0, Code::entry_point_offset())); | 357 __ lw(T0, FieldAddress(T0, Code::entry_point_offset())); |
358 | 358 |
359 // Remove the stub frame. | 359 // Remove the stub frame. |
360 __ LeaveStubFrameAndReturn(T0); | 360 __ LeaveStubFrameAndReturn(T0); |
361 } | 361 } |
362 | 362 |
363 | 363 |
364 // Called from object allocate instruction when the allocation stub has been | 364 // Called from object allocate instruction when the allocation stub has been |
365 // disabled. | 365 // disabled. |
366 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { | 366 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { |
367 __ Comment("FixAllocationStubTarget"); | 367 __ Comment("FixAllocationStubTarget"); |
368 __ EnterStubFrame(); | 368 __ EnterStubFrame(); |
369 // Setup space on stack for return value. | 369 // Setup space on stack for return value. |
370 __ addiu(SP, SP, Immediate(-1 * kWordSize)); | 370 __ addiu(SP, SP, Immediate(-1 * kWordSize)); |
371 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 371 __ LoadObject(TMP, Object::null_object()); |
372 __ sw(TMP, Address(SP, 0 * kWordSize)); | 372 __ sw(TMP, Address(SP, 0 * kWordSize)); |
373 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); | 373 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); |
374 // Get Code object result. | 374 // Get Code object result. |
375 __ lw(T0, Address(SP, 0 * kWordSize)); | 375 __ lw(T0, Address(SP, 0 * kWordSize)); |
376 __ addiu(SP, SP, Immediate(1 * kWordSize)); | 376 __ addiu(SP, SP, Immediate(1 * kWordSize)); |
377 | 377 |
378 // Jump to the dart function. | 378 // Jump to the dart function. |
379 __ lw(T0, FieldAddress(T0, Code::entry_point_offset())); | 379 __ lw(T0, FieldAddress(T0, Code::entry_point_offset())); |
380 | 380 |
381 // Remove the stub frame. | 381 // Remove the stub frame. |
382 __ LeaveStubFrameAndReturn(T0); | 382 __ LeaveStubFrameAndReturn(T0); |
383 } | 383 } |
384 | 384 |
385 | 385 |
386 // Input parameters: | 386 // Input parameters: |
387 // A1: Smi-tagged argument count, may be zero. | 387 // A1: Smi-tagged argument count, may be zero. |
388 // FP[kParamEndSlotFromFp + 1]: Last argument. | 388 // FP[kParamEndSlotFromFp + 1]: Last argument. |
389 static void PushArgumentsArray(Assembler* assembler) { | 389 static void PushArgumentsArray(Assembler* assembler) { |
390 __ Comment("PushArgumentsArray"); | 390 __ Comment("PushArgumentsArray"); |
391 // Allocate array to store arguments of caller. | 391 // Allocate array to store arguments of caller. |
392 __ LoadImmediate(A0, reinterpret_cast<intptr_t>(Object::null())); | 392 __ LoadObject(A0, Object::null_object()); |
393 // A0: Null element type for raw Array. | 393 // A0: Null element type for raw Array. |
394 // A1: Smi-tagged argument count, may be zero. | 394 // A1: Smi-tagged argument count, may be zero. |
395 __ BranchLink(*StubCode::AllocateArray_entry()); | 395 __ BranchLink(*StubCode::AllocateArray_entry()); |
396 __ Comment("PushArgumentsArray return"); | 396 __ Comment("PushArgumentsArray return"); |
397 // V0: newly allocated array. | 397 // V0: newly allocated array. |
398 // A1: Smi-tagged argument count, may be zero (was preserved by the stub). | 398 // A1: Smi-tagged argument count, may be zero (was preserved by the stub). |
399 __ Push(V0); // Array is in V0 and on top of stack. | 399 __ Push(V0); // Array is in V0 and on top of stack. |
400 __ sll(T1, A1, 1); | 400 __ sll(T1, A1, 1); |
401 __ addu(T1, FP, T1); | 401 __ addu(T1, FP, T1); |
402 __ AddImmediate(T1, kParamEndSlotFromFp * kWordSize); | 402 __ AddImmediate(T1, kParamEndSlotFromFp * kWordSize); |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
561 __ sll(TMP, A1, 1); // A1 is a Smi. | 561 __ sll(TMP, A1, 1); // A1 is a Smi. |
562 __ addu(TMP, FP, TMP); | 562 __ addu(TMP, FP, TMP); |
563 __ lw(T6, Address(TMP, kParamEndSlotFromFp * kWordSize)); | 563 __ lw(T6, Address(TMP, kParamEndSlotFromFp * kWordSize)); |
564 | 564 |
565 // Push space for the return value. | 565 // Push space for the return value. |
566 // Push the receiver. | 566 // Push the receiver. |
567 // Push IC data object. | 567 // Push IC data object. |
568 // Push arguments descriptor array. | 568 // Push arguments descriptor array. |
569 // Push original arguments array. | 569 // Push original arguments array. |
570 __ addiu(SP, SP, Immediate(-4 * kWordSize)); | 570 __ addiu(SP, SP, Immediate(-4 * kWordSize)); |
571 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 571 __ LoadObject(TMP, Object::null_object()); |
572 __ sw(TMP, Address(SP, 3 * kWordSize)); | 572 __ sw(TMP, Address(SP, 3 * kWordSize)); |
573 __ sw(T6, Address(SP, 2 * kWordSize)); | 573 __ sw(T6, Address(SP, 2 * kWordSize)); |
574 __ sw(S5, Address(SP, 1 * kWordSize)); | 574 __ sw(S5, Address(SP, 1 * kWordSize)); |
575 __ sw(S4, Address(SP, 0 * kWordSize)); | 575 __ sw(S4, Address(SP, 0 * kWordSize)); |
576 // A1: Smi-tagged arguments array length. | 576 // A1: Smi-tagged arguments array length. |
577 PushArgumentsArray(assembler); | 577 PushArgumentsArray(assembler); |
578 const intptr_t kNumArgs = 4; | 578 const intptr_t kNumArgs = 4; |
579 __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs); | 579 __ CallRuntime(kInvokeNoSuchMethodDispatcherRuntimeEntry, kNumArgs); |
580 __ lw(V0, Address(SP, 4 * kWordSize)); // Return value. | 580 __ lw(V0, Address(SP, 4 * kWordSize)); // Return value. |
581 __ addiu(SP, SP, Immediate(5 * kWordSize)); | 581 __ addiu(SP, SP, Immediate(5 * kWordSize)); |
(...skipping 13 matching lines...) Expand all Loading... |
595 | 595 |
596 // Preserve IC data and arguments descriptor. | 596 // Preserve IC data and arguments descriptor. |
597 __ addiu(SP, SP, Immediate(-6 * kWordSize)); | 597 __ addiu(SP, SP, Immediate(-6 * kWordSize)); |
598 __ sw(S5, Address(SP, 5 * kWordSize)); | 598 __ sw(S5, Address(SP, 5 * kWordSize)); |
599 __ sw(S4, Address(SP, 4 * kWordSize)); | 599 __ sw(S4, Address(SP, 4 * kWordSize)); |
600 | 600 |
601 // Push space for the return value. | 601 // Push space for the return value. |
602 // Push the receiver. | 602 // Push the receiver. |
603 // Push IC data object. | 603 // Push IC data object. |
604 // Push arguments descriptor array. | 604 // Push arguments descriptor array. |
605 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 605 __ LoadObject(TMP, Object::null_object()); |
606 __ sw(TMP, Address(SP, 3 * kWordSize)); | 606 __ sw(TMP, Address(SP, 3 * kWordSize)); |
607 __ sw(T6, Address(SP, 2 * kWordSize)); | 607 __ sw(T6, Address(SP, 2 * kWordSize)); |
608 __ sw(S5, Address(SP, 1 * kWordSize)); | 608 __ sw(S5, Address(SP, 1 * kWordSize)); |
609 __ sw(S4, Address(SP, 0 * kWordSize)); | 609 __ sw(S4, Address(SP, 0 * kWordSize)); |
610 | 610 |
611 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); | 611 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
612 | 612 |
613 __ lw(T0, Address(SP, 3 * kWordSize)); // Get result function. | 613 __ lw(T0, Address(SP, 3 * kWordSize)); // Get result function. |
614 __ lw(S4, Address(SP, 4 * kWordSize)); // Restore argument descriptor. | 614 __ lw(S4, Address(SP, 4 * kWordSize)); // Restore argument descriptor. |
615 __ lw(S5, Address(SP, 5 * kWordSize)); // Restore IC data. | 615 __ lw(S5, Address(SP, 5 * kWordSize)); // Restore IC data. |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
724 // Store the type argument field. | 724 // Store the type argument field. |
725 __ StoreIntoObjectNoBarrier(T0, | 725 __ StoreIntoObjectNoBarrier(T0, |
726 FieldAddress(T0, Array::type_arguments_offset()), | 726 FieldAddress(T0, Array::type_arguments_offset()), |
727 A0); | 727 A0); |
728 | 728 |
729 // Set the length field. | 729 // Set the length field. |
730 __ StoreIntoObjectNoBarrier(T0, | 730 __ StoreIntoObjectNoBarrier(T0, |
731 FieldAddress(T0, Array::length_offset()), | 731 FieldAddress(T0, Array::length_offset()), |
732 A1); | 732 A1); |
733 | 733 |
734 __ LoadImmediate(T7, reinterpret_cast<int32_t>(Object::null())); | 734 __ LoadObject(T7, Object::null_object()); |
735 // Initialize all array elements to raw_null. | 735 // Initialize all array elements to raw_null. |
736 // T0: new object start as a tagged pointer. | 736 // T0: new object start as a tagged pointer. |
737 // T1: new object end address. | 737 // T1: new object end address. |
738 // T2: iterator which initially points to the start of the variable | 738 // T2: iterator which initially points to the start of the variable |
739 // data area to be initialized. | 739 // data area to be initialized. |
740 // T7: null. | 740 // T7: null. |
741 __ AddImmediate(T2, T0, sizeof(RawArray) - kHeapObjectTag); | 741 __ AddImmediate(T2, T0, sizeof(RawArray) - kHeapObjectTag); |
742 | 742 |
743 Label done; | 743 Label done; |
744 Label init_loop; | 744 Label init_loop; |
745 __ Bind(&init_loop); | 745 __ Bind(&init_loop); |
746 __ BranchUnsignedGreaterEqual(T2, T1, &done); | 746 __ BranchUnsignedGreaterEqual(T2, T1, &done); |
747 __ sw(T7, Address(T2, 0)); | 747 __ sw(T7, Address(T2, 0)); |
748 __ b(&init_loop); | 748 __ b(&init_loop); |
749 __ delay_slot()->addiu(T2, T2, Immediate(kWordSize)); | 749 __ delay_slot()->addiu(T2, T2, Immediate(kWordSize)); |
750 __ Bind(&done); | 750 __ Bind(&done); |
751 | 751 |
752 __ Ret(); // Returns the newly allocated object in V0. | 752 __ Ret(); // Returns the newly allocated object in V0. |
753 __ delay_slot()->mov(V0, T0); | 753 __ delay_slot()->mov(V0, T0); |
754 | 754 |
755 // Unable to allocate the array using the fast inline code, just call | 755 // Unable to allocate the array using the fast inline code, just call |
756 // into the runtime. | 756 // into the runtime. |
757 __ Bind(&slow_case); | 757 __ Bind(&slow_case); |
758 // Create a stub frame as we are pushing some objects on the stack before | 758 // Create a stub frame as we are pushing some objects on the stack before |
759 // calling into the runtime. | 759 // calling into the runtime. |
760 __ EnterStubFrame(); | 760 __ EnterStubFrame(); |
761 // Setup space on stack for return value. | 761 // Setup space on stack for return value. |
762 // Push array length as Smi and element type. | 762 // Push array length as Smi and element type. |
763 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 763 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
764 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 764 __ LoadObject(TMP, Object::null_object()); |
765 __ sw(TMP, Address(SP, 2 * kWordSize)); | 765 __ sw(TMP, Address(SP, 2 * kWordSize)); |
766 __ sw(A1, Address(SP, 1 * kWordSize)); | 766 __ sw(A1, Address(SP, 1 * kWordSize)); |
767 __ sw(A0, Address(SP, 0 * kWordSize)); | 767 __ sw(A0, Address(SP, 0 * kWordSize)); |
768 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); | 768 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); |
769 __ Comment("AllocateArrayStub return"); | 769 __ Comment("AllocateArrayStub return"); |
770 // Pop arguments; result is popped in IP. | 770 // Pop arguments; result is popped in IP. |
771 __ lw(V0, Address(SP, 2 * kWordSize)); | 771 __ lw(V0, Address(SP, 2 * kWordSize)); |
772 __ lw(A1, Address(SP, 1 * kWordSize)); | 772 __ lw(A1, Address(SP, 1 * kWordSize)); |
773 __ lw(A0, Address(SP, 0 * kWordSize)); | 773 __ lw(A0, Address(SP, 0 * kWordSize)); |
774 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 774 __ addiu(SP, SP, Immediate(3 * kWordSize)); |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
988 // T2: size and bit tags. | 988 // T2: size and bit tags. |
989 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid)); | 989 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid)); |
990 __ or_(T2, T2, TMP); | 990 __ or_(T2, T2, TMP); |
991 __ sw(T2, FieldAddress(V0, Context::tags_offset())); | 991 __ sw(T2, FieldAddress(V0, Context::tags_offset())); |
992 | 992 |
993 // Setup up number of context variables field. | 993 // Setup up number of context variables field. |
994 // V0: new object. | 994 // V0: new object. |
995 // T1: number of context variables as integer value (not object). | 995 // T1: number of context variables as integer value (not object). |
996 __ sw(T1, FieldAddress(V0, Context::num_variables_offset())); | 996 __ sw(T1, FieldAddress(V0, Context::num_variables_offset())); |
997 | 997 |
998 __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); | 998 __ LoadObject(T7, Object::null_object()); |
999 | 999 |
1000 // Initialize the context variables. | 1000 // Initialize the context variables. |
1001 // V0: new object. | 1001 // V0: new object. |
1002 // T1: number of context variables. | 1002 // T1: number of context variables. |
1003 Label loop, loop_exit; | 1003 Label loop, loop_exit; |
1004 __ blez(T1, &loop_exit); | 1004 __ blez(T1, &loop_exit); |
1005 // Setup the parent field. | 1005 // Setup the parent field. |
1006 __ delay_slot()->sw(T7, FieldAddress(V0, Context::parent_offset())); | 1006 __ delay_slot()->sw(T7, FieldAddress(V0, Context::parent_offset())); |
1007 __ AddImmediate(T3, V0, Context::variable_offset(0) - kHeapObjectTag); | 1007 __ AddImmediate(T3, V0, Context::variable_offset(0) - kHeapObjectTag); |
1008 __ sll(T1, T1, 2); | 1008 __ sll(T1, T1, 2); |
1009 __ Bind(&loop); | 1009 __ Bind(&loop); |
1010 __ addiu(T1, T1, Immediate(-kWordSize)); | 1010 __ addiu(T1, T1, Immediate(-kWordSize)); |
1011 __ addu(T4, T3, T1); | 1011 __ addu(T4, T3, T1); |
1012 __ bgtz(T1, &loop); | 1012 __ bgtz(T1, &loop); |
1013 __ delay_slot()->sw(T7, Address(T4)); | 1013 __ delay_slot()->sw(T7, Address(T4)); |
1014 __ Bind(&loop_exit); | 1014 __ Bind(&loop_exit); |
1015 | 1015 |
1016 // Done allocating and initializing the context. | 1016 // Done allocating and initializing the context. |
1017 // V0: new object. | 1017 // V0: new object. |
1018 __ Ret(); | 1018 __ Ret(); |
1019 | 1019 |
1020 __ Bind(&slow_case); | 1020 __ Bind(&slow_case); |
1021 } | 1021 } |
1022 // Create a stub frame as we are pushing some objects on the stack before | 1022 // Create a stub frame as we are pushing some objects on the stack before |
1023 // calling into the runtime. | 1023 // calling into the runtime. |
1024 __ EnterStubFrame(); | 1024 __ EnterStubFrame(); |
1025 // Setup space on stack for return value. | 1025 // Setup space on stack for return value. |
1026 __ SmiTag(T1); | 1026 __ SmiTag(T1); |
1027 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 1027 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
1028 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 1028 __ LoadObject(TMP, Object::null_object()); |
1029 __ sw(TMP, Address(SP, 1 * kWordSize)); // Store null. | 1029 __ sw(TMP, Address(SP, 1 * kWordSize)); // Store null. |
1030 __ sw(T1, Address(SP, 0 * kWordSize)); | 1030 __ sw(T1, Address(SP, 0 * kWordSize)); |
1031 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. | 1031 __ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context. |
1032 __ lw(V0, Address(SP, 1 * kWordSize)); // Get the new context. | 1032 __ lw(V0, Address(SP, 1 * kWordSize)); // Get the new context. |
1033 __ addiu(SP, SP, Immediate(2 * kWordSize)); // Pop argument and return. | 1033 __ addiu(SP, SP, Immediate(2 * kWordSize)); // Pop argument and return. |
1034 | 1034 |
1035 // V0: new object | 1035 // V0: new object |
1036 // Restore the frame pointer. | 1036 // Restore the frame pointer. |
1037 __ LeaveStubFrameAndReturn(); | 1037 __ LeaveStubFrameAndReturn(); |
1038 } | 1038 } |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1160 // T3: next object start. | 1160 // T3: next object start. |
1161 // T1: new object type arguments (if is_cls_parameterized). | 1161 // T1: new object type arguments (if is_cls_parameterized). |
1162 // Set the tags. | 1162 // Set the tags. |
1163 uword tags = 0; | 1163 uword tags = 0; |
1164 tags = RawObject::SizeTag::update(instance_size, tags); | 1164 tags = RawObject::SizeTag::update(instance_size, tags); |
1165 ASSERT(cls.id() != kIllegalCid); | 1165 ASSERT(cls.id() != kIllegalCid); |
1166 tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1166 tags = RawObject::ClassIdTag::update(cls.id(), tags); |
1167 __ LoadImmediate(T0, tags); | 1167 __ LoadImmediate(T0, tags); |
1168 __ sw(T0, Address(T2, Instance::tags_offset())); | 1168 __ sw(T0, Address(T2, Instance::tags_offset())); |
1169 | 1169 |
1170 __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); | 1170 __ LoadObject(T7, Object::null_object()); |
1171 | 1171 |
1172 // Initialize the remaining words of the object. | 1172 // Initialize the remaining words of the object. |
1173 // T2: new object start. | 1173 // T2: new object start. |
1174 // T3: next object start. | 1174 // T3: next object start. |
1175 // T1: new object type arguments (if is_cls_parameterized). | 1175 // T1: new object type arguments (if is_cls_parameterized). |
1176 // First try inlining the initialization without a loop. | 1176 // First try inlining the initialization without a loop. |
1177 if (instance_size < (kInlineInstanceSize * kWordSize)) { | 1177 if (instance_size < (kInlineInstanceSize * kWordSize)) { |
1178 // Check if the object contains any non-header fields. | 1178 // Check if the object contains any non-header fields. |
1179 // Small objects are initialized using a consecutive set of writes. | 1179 // Small objects are initialized using a consecutive set of writes. |
1180 for (intptr_t current_offset = Instance::NextFieldOffset(); | 1180 for (intptr_t current_offset = Instance::NextFieldOffset(); |
(...skipping 30 matching lines...) Expand all Loading... |
1211 } | 1211 } |
1212 // If is_cls_parameterized: | 1212 // If is_cls_parameterized: |
1213 // T1: new object type arguments (instantiated or not). | 1213 // T1: new object type arguments (instantiated or not). |
1214 // Create a stub frame as we are pushing some objects on the stack before | 1214 // Create a stub frame as we are pushing some objects on the stack before |
1215 // calling into the runtime. | 1215 // calling into the runtime. |
1216 __ EnterStubFrame(); // Uses pool pointer to pass cls to runtime. | 1216 __ EnterStubFrame(); // Uses pool pointer to pass cls to runtime. |
1217 __ LoadObject(TMP, cls); | 1217 __ LoadObject(TMP, cls); |
1218 | 1218 |
1219 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 1219 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
1220 // Space on stack for return value. | 1220 // Space on stack for return value. |
1221 __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); | 1221 __ LoadObject(T7, Object::null_object()); |
1222 __ sw(T7, Address(SP, 2 * kWordSize)); | 1222 __ sw(T7, Address(SP, 2 * kWordSize)); |
1223 __ sw(TMP, Address(SP, 1 * kWordSize)); // Class of object to be allocated. | 1223 __ sw(TMP, Address(SP, 1 * kWordSize)); // Class of object to be allocated. |
1224 | 1224 |
1225 if (is_cls_parameterized) { | 1225 if (is_cls_parameterized) { |
1226 // Push type arguments of object to be allocated and of instantiator. | 1226 // Push type arguments of object to be allocated and of instantiator. |
1227 __ sw(T1, Address(SP, 0 * kWordSize)); | 1227 __ sw(T1, Address(SP, 0 * kWordSize)); |
1228 } else { | 1228 } else { |
1229 // Push null type arguments. | 1229 // Push null type arguments. |
1230 __ sw(T7, Address(SP, 0 * kWordSize)); | 1230 __ sw(T7, Address(SP, 0 * kWordSize)); |
1231 } | 1231 } |
(...skipping 24 matching lines...) Expand all Loading... |
1256 __ lw(A1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); | 1256 __ lw(A1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); |
1257 __ sll(TMP, A1, 1); // A1 is a Smi. | 1257 __ sll(TMP, A1, 1); // A1 is a Smi. |
1258 __ addu(TMP, FP, TMP); | 1258 __ addu(TMP, FP, TMP); |
1259 __ lw(T6, Address(TMP, kParamEndSlotFromFp * kWordSize)); | 1259 __ lw(T6, Address(TMP, kParamEndSlotFromFp * kWordSize)); |
1260 | 1260 |
1261 // Push space for the return value. | 1261 // Push space for the return value. |
1262 // Push the receiver. | 1262 // Push the receiver. |
1263 // Push arguments descriptor array. | 1263 // Push arguments descriptor array. |
1264 const intptr_t kNumArgs = 3; | 1264 const intptr_t kNumArgs = 3; |
1265 __ addiu(SP, SP, Immediate(-kNumArgs * kWordSize)); | 1265 __ addiu(SP, SP, Immediate(-kNumArgs * kWordSize)); |
1266 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 1266 __ LoadObject(TMP, Object::null_object()); |
1267 __ sw(TMP, Address(SP, 2 * kWordSize)); | 1267 __ sw(TMP, Address(SP, 2 * kWordSize)); |
1268 __ sw(T6, Address(SP, 1 * kWordSize)); | 1268 __ sw(T6, Address(SP, 1 * kWordSize)); |
1269 __ sw(S4, Address(SP, 0 * kWordSize)); | 1269 __ sw(S4, Address(SP, 0 * kWordSize)); |
1270 | 1270 |
1271 // A1: Smi-tagged arguments array length. | 1271 // A1: Smi-tagged arguments array length. |
1272 PushArgumentsArray(assembler); | 1272 PushArgumentsArray(assembler); |
1273 | 1273 |
1274 __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs); | 1274 __ CallRuntime(kInvokeClosureNoSuchMethodRuntimeEntry, kNumArgs); |
1275 // noSuchMethod on closures always throws an error, so it will never return. | 1275 // noSuchMethod on closures always throws an error, so it will never return. |
1276 __ break_(0); | 1276 __ break_(0); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1532 // T1: address of receiver. | 1532 // T1: address of receiver. |
1533 // Create a stub frame as we are pushing some objects on the stack before | 1533 // Create a stub frame as we are pushing some objects on the stack before |
1534 // calling into the runtime. | 1534 // calling into the runtime. |
1535 __ EnterStubFrame(); | 1535 __ EnterStubFrame(); |
1536 // Preserve IC data object and arguments descriptor array and | 1536 // Preserve IC data object and arguments descriptor array and |
1537 // setup space on stack for result (target code object). | 1537 // setup space on stack for result (target code object). |
1538 int num_slots = num_args + 4; | 1538 int num_slots = num_args + 4; |
1539 __ addiu(SP, SP, Immediate(-num_slots * kWordSize)); | 1539 __ addiu(SP, SP, Immediate(-num_slots * kWordSize)); |
1540 __ sw(S5, Address(SP, (num_slots - 1) * kWordSize)); | 1540 __ sw(S5, Address(SP, (num_slots - 1) * kWordSize)); |
1541 __ sw(S4, Address(SP, (num_slots - 2) * kWordSize)); | 1541 __ sw(S4, Address(SP, (num_slots - 2) * kWordSize)); |
1542 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 1542 __ LoadObject(TMP, Object::null_object()); |
1543 __ sw(TMP, Address(SP, (num_slots - 3) * kWordSize)); | 1543 __ sw(TMP, Address(SP, (num_slots - 3) * kWordSize)); |
1544 // Push call arguments. | 1544 // Push call arguments. |
1545 for (intptr_t i = 0; i < num_args; i++) { | 1545 for (intptr_t i = 0; i < num_args; i++) { |
1546 __ lw(TMP, Address(T1, -i * kWordSize)); | 1546 __ lw(TMP, Address(T1, -i * kWordSize)); |
1547 __ sw(TMP, Address(SP, (num_slots - i - 4) * kWordSize)); | 1547 __ sw(TMP, Address(SP, (num_slots - i - 4) * kWordSize)); |
1548 } | 1548 } |
1549 // Pass IC data object. | 1549 // Pass IC data object. |
1550 __ sw(S5, Address(SP, (num_slots - num_args - 4) * kWordSize)); | 1550 __ sw(S5, Address(SP, (num_slots - num_args - 4) * kWordSize)); |
1551 __ CallRuntime(handle_ic_miss, num_args + 1); | 1551 __ CallRuntime(handle_ic_miss, num_args + 1); |
1552 __ Comment("NArgsCheckInlineCacheStub return"); | 1552 __ Comment("NArgsCheckInlineCacheStub return"); |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1831 __ jr(T2); | 1831 __ jr(T2); |
1832 } | 1832 } |
1833 | 1833 |
1834 | 1834 |
1835 // S5: Contains an ICData. | 1835 // S5: Contains an ICData. |
1836 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { | 1836 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { |
1837 __ Comment("ICCallBreakpoint stub"); | 1837 __ Comment("ICCallBreakpoint stub"); |
1838 __ EnterStubFrame(); | 1838 __ EnterStubFrame(); |
1839 __ addiu(SP, SP, Immediate(-2 * kWordSize)); | 1839 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
1840 __ sw(S5, Address(SP, 1 * kWordSize)); | 1840 __ sw(S5, Address(SP, 1 * kWordSize)); |
1841 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 1841 __ LoadObject(TMP, Object::null_object()); |
1842 __ sw(TMP, Address(SP, 0 * kWordSize)); | 1842 __ sw(TMP, Address(SP, 0 * kWordSize)); |
1843 | 1843 |
1844 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); | 1844 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
1845 | 1845 |
1846 __ lw(S5, Address(SP, 1 * kWordSize)); | 1846 __ lw(S5, Address(SP, 1 * kWordSize)); |
1847 __ lw(T0, Address(SP, 0 * kWordSize)); | 1847 __ lw(T0, Address(SP, 0 * kWordSize)); |
1848 __ addiu(SP, SP, Immediate(2 * kWordSize)); | 1848 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
1849 __ LeaveStubFrame(); | 1849 __ LeaveStubFrame(); |
1850 __ jr(T0); | 1850 __ jr(T0); |
1851 } | 1851 } |
1852 | 1852 |
1853 | 1853 |
1854 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) { | 1854 void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) { |
1855 __ Comment("RuntimeCallBreakpoint stub"); | 1855 __ Comment("RuntimeCallBreakpoint stub"); |
1856 __ EnterStubFrame(); | 1856 __ EnterStubFrame(); |
1857 __ addiu(SP, SP, Immediate(-1 * kWordSize)); | 1857 __ addiu(SP, SP, Immediate(-1 * kWordSize)); |
1858 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 1858 __ LoadObject(TMP, Object::null_object()); |
1859 __ sw(TMP, Address(SP, 0 * kWordSize)); | 1859 __ sw(TMP, Address(SP, 0 * kWordSize)); |
1860 | 1860 |
1861 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); | 1861 __ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0); |
1862 | 1862 |
1863 __ lw(T0, Address(SP, 0 * kWordSize)); | 1863 __ lw(T0, Address(SP, 0 * kWordSize)); |
1864 __ addiu(SP, SP, Immediate(3 * kWordSize)); | 1864 __ addiu(SP, SP, Immediate(3 * kWordSize)); |
1865 __ LeaveStubFrame(); | 1865 __ LeaveStubFrame(); |
1866 __ jr(T0); | 1866 __ jr(T0); |
1867 } | 1867 } |
1868 | 1868 |
(...skipping 30 matching lines...) Expand all Loading... |
1899 // A2: cache array. | 1899 // A2: cache array. |
1900 // Result in V0: null -> not found, otherwise result (true or false). | 1900 // Result in V0: null -> not found, otherwise result (true or false). |
1901 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { | 1901 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { |
1902 __ Comment("SubtypeNTestCacheStub"); | 1902 __ Comment("SubtypeNTestCacheStub"); |
1903 ASSERT((1 <= n) && (n <= 3)); | 1903 ASSERT((1 <= n) && (n <= 3)); |
1904 if (n > 1) { | 1904 if (n > 1) { |
1905 // Get instance type arguments. | 1905 // Get instance type arguments. |
1906 __ LoadClass(T0, A0); | 1906 __ LoadClass(T0, A0); |
1907 // Compute instance type arguments into T1. | 1907 // Compute instance type arguments into T1. |
1908 Label has_no_type_arguments; | 1908 Label has_no_type_arguments; |
1909 __ LoadImmediate(T1, reinterpret_cast<intptr_t>(Object::null())); | 1909 __ LoadObject(T1, Object::null_object()); |
1910 __ lw(T2, FieldAddress(T0, | 1910 __ lw(T2, FieldAddress(T0, |
1911 Class::type_arguments_field_offset_in_words_offset())); | 1911 Class::type_arguments_field_offset_in_words_offset())); |
1912 __ BranchEqual( | 1912 __ BranchEqual( |
1913 T2, Immediate(Class::kNoTypeArguments), &has_no_type_arguments); | 1913 T2, Immediate(Class::kNoTypeArguments), &has_no_type_arguments); |
1914 __ sll(T2, T2, 2); | 1914 __ sll(T2, T2, 2); |
1915 __ addu(T2, A0, T2); // T2 <- A0 + T2 * 4 | 1915 __ addu(T2, A0, T2); // T2 <- A0 + T2 * 4 |
1916 __ lw(T1, FieldAddress(T2, 0)); | 1916 __ lw(T1, FieldAddress(T2, 0)); |
1917 __ Bind(&has_no_type_arguments); | 1917 __ Bind(&has_no_type_arguments); |
1918 } | 1918 } |
1919 __ LoadClassId(T0, A0); | 1919 __ LoadClassId(T0, A0); |
1920 // A0: instance. | 1920 // A0: instance. |
1921 // A1: instantiator type arguments or NULL. | 1921 // A1: instantiator type arguments or NULL. |
1922 // A2: SubtypeTestCache. | 1922 // A2: SubtypeTestCache. |
1923 // T0: instance class id. | 1923 // T0: instance class id. |
1924 // T1: instance type arguments (null if none), used only if n > 1. | 1924 // T1: instance type arguments (null if none), used only if n > 1. |
1925 __ lw(T2, FieldAddress(A2, SubtypeTestCache::cache_offset())); | 1925 __ lw(T2, FieldAddress(A2, SubtypeTestCache::cache_offset())); |
1926 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); | 1926 __ AddImmediate(T2, Array::data_offset() - kHeapObjectTag); |
1927 | 1927 |
1928 __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); | 1928 __ LoadObject(T7, Object::null_object()); |
1929 | 1929 |
1930 Label loop, found, not_found, next_iteration; | 1930 Label loop, found, not_found, next_iteration; |
1931 // T0: instance class id. | 1931 // T0: instance class id. |
1932 // T1: instance type arguments. | 1932 // T1: instance type arguments. |
1933 // T2: Entry start. | 1933 // T2: Entry start. |
1934 // T7: null. | 1934 // T7: null. |
1935 __ SmiTag(T0); | 1935 __ SmiTag(T0); |
1936 __ Bind(&loop); | 1936 __ Bind(&loop); |
1937 __ lw(T3, Address(T2, kWordSize * SubtypeTestCache::kInstanceClassId)); | 1937 __ lw(T3, Address(T2, kWordSize * SubtypeTestCache::kInstanceClassId)); |
1938 __ beq(T3, T7, ¬_found); | 1938 __ beq(T3, T7, ¬_found); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2041 | 2041 |
2042 // Calls to the runtime to optimize the given function. | 2042 // Calls to the runtime to optimize the given function. |
2043 // T0: function to be reoptimized. | 2043 // T0: function to be reoptimized. |
2044 // S4: argument descriptor (preserved). | 2044 // S4: argument descriptor (preserved). |
2045 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { | 2045 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { |
2046 __ Comment("OptimizeFunctionStub"); | 2046 __ Comment("OptimizeFunctionStub"); |
2047 __ EnterStubFrame(); | 2047 __ EnterStubFrame(); |
2048 __ addiu(SP, SP, Immediate(-3 * kWordSize)); | 2048 __ addiu(SP, SP, Immediate(-3 * kWordSize)); |
2049 __ sw(S4, Address(SP, 2 * kWordSize)); | 2049 __ sw(S4, Address(SP, 2 * kWordSize)); |
2050 // Setup space on stack for return value. | 2050 // Setup space on stack for return value. |
2051 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); | 2051 __ LoadObject(TMP, Object::null_object()); |
2052 __ sw(TMP, Address(SP, 1 * kWordSize)); | 2052 __ sw(TMP, Address(SP, 1 * kWordSize)); |
2053 __ sw(T0, Address(SP, 0 * kWordSize)); | 2053 __ sw(T0, Address(SP, 0 * kWordSize)); |
2054 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); | 2054 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); |
2055 __ Comment("OptimizeFunctionStub return"); | 2055 __ Comment("OptimizeFunctionStub return"); |
2056 __ lw(T0, Address(SP, 1 * kWordSize)); // Get Code object | 2056 __ lw(T0, Address(SP, 1 * kWordSize)); // Get Code object |
2057 __ lw(S4, Address(SP, 2 * kWordSize)); // Restore argument descriptor. | 2057 __ lw(S4, Address(SP, 2 * kWordSize)); // Restore argument descriptor. |
2058 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Discard argument. | 2058 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Discard argument. |
2059 | 2059 |
2060 __ lw(T0, FieldAddress(T0, Code::entry_point_offset())); | 2060 __ lw(T0, FieldAddress(T0, Code::entry_point_offset())); |
2061 __ LeaveStubFrameAndReturn(T0); | 2061 __ LeaveStubFrameAndReturn(T0); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2248 // Result: | 2248 // Result: |
2249 // T1: entry point. | 2249 // T1: entry point. |
2250 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { | 2250 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { |
2251 EmitMegamorphicLookup(assembler, T0, T1, T1); | 2251 EmitMegamorphicLookup(assembler, T0, T1, T1); |
2252 __ Ret(); | 2252 __ Ret(); |
2253 } | 2253 } |
2254 | 2254 |
2255 } // namespace dart | 2255 } // namespace dart |
2256 | 2256 |
2257 #endif // defined TARGET_ARCH_MIPS | 2257 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |