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