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

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

Issue 1074533002: Replace MIPS TraceSimMsg calls with Comment calls. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 8 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/intermediate_language_mips.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_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 23 matching lines...) Expand all
34 // S5 : address of the runtime function to call. 34 // S5 : address of the runtime function to call.
35 // S4 : number of arguments to the call. 35 // S4 : number of arguments to the call.
36 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) { 36 void StubCode::GenerateCallToRuntimeStub(Assembler* assembler) {
37 const intptr_t isolate_offset = NativeArguments::isolate_offset(); 37 const intptr_t isolate_offset = NativeArguments::isolate_offset();
38 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); 38 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
39 const intptr_t argv_offset = NativeArguments::argv_offset(); 39 const intptr_t argv_offset = NativeArguments::argv_offset();
40 const intptr_t retval_offset = NativeArguments::retval_offset(); 40 const intptr_t retval_offset = NativeArguments::retval_offset();
41 const intptr_t exitframe_last_param_slot_from_fp = 2; 41 const intptr_t exitframe_last_param_slot_from_fp = 2;
42 42
43 __ SetPrologueOffset(); 43 __ SetPrologueOffset();
44 __ TraceSimMsg("CallToRuntimeStub"); 44 __ Comment("CallToRuntimeStub");
45 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 45 __ addiu(SP, SP, Immediate(-3 * kWordSize));
46 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker 46 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker
47 __ sw(RA, Address(SP, 1 * kWordSize)); 47 __ sw(RA, Address(SP, 1 * kWordSize));
48 __ sw(FP, Address(SP, 0 * kWordSize)); 48 __ sw(FP, Address(SP, 0 * kWordSize));
49 __ mov(FP, SP); 49 __ mov(FP, SP);
50 50
51 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S6)) != 0); 51 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S6)) != 0);
52 __ LoadIsolate(S6); 52 __ LoadIsolate(S6);
53 53
54 // Save exit frame information to enable stack walking as we are about 54 // Save exit frame information to enable stack walking as we are about
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 94
95 // Call runtime or redirection via simulator. 95 // Call runtime or redirection via simulator.
96 // We defensively always jalr through T9 because it is sometimes required by 96 // We defensively always jalr through T9 because it is sometimes required by
97 // the MIPS ABI. 97 // the MIPS ABI.
98 __ mov(T9, S5); 98 __ mov(T9, S5);
99 __ jalr(T9); 99 __ jalr(T9);
100 100
101 ASSERT(retval_offset == 3 * kWordSize); 101 ASSERT(retval_offset == 3 * kWordSize);
102 // Retval is next to 1st argument. 102 // Retval is next to 1st argument.
103 __ delay_slot()->addiu(A3, A2, Immediate(kWordSize)); 103 __ delay_slot()->addiu(A3, A2, Immediate(kWordSize));
104 __ TraceSimMsg("CallToRuntimeStub return"); 104 __ Comment("CallToRuntimeStub return");
105 105
106 // Mark that the isolate is executing Dart code. 106 // Mark that the isolate is executing Dart code.
107 __ LoadImmediate(A2, VMTag::kDartTagId); 107 __ LoadImmediate(A2, VMTag::kDartTagId);
108 __ sw(A2, Address(S6, Isolate::vm_tag_offset())); 108 __ sw(A2, Address(S6, Isolate::vm_tag_offset()));
109 109
110 // Reset exit frame information in Isolate structure. 110 // Reset exit frame information in Isolate structure.
111 __ sw(ZR, Address(S6, Isolate::top_exit_frame_info_offset())); 111 __ sw(ZR, Address(S6, Isolate::top_exit_frame_info_offset()));
112 112
113 __ mov(SP, FP); 113 __ mov(SP, FP);
114 __ lw(RA, Address(SP, 1 * kWordSize)); 114 __ lw(RA, Address(SP, 1 * kWordSize));
(...skipping 28 matching lines...) Expand all
143 // T5 : address of the native function to call. 143 // T5 : address of the native function to call.
144 // A2 : address of first argument in argument array. 144 // A2 : address of first argument in argument array.
145 // A1 : argc_tag including number of arguments and function kind. 145 // A1 : argc_tag including number of arguments and function kind.
146 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) { 146 void StubCode::GenerateCallNativeCFunctionStub(Assembler* assembler) {
147 const intptr_t isolate_offset = NativeArguments::isolate_offset(); 147 const intptr_t isolate_offset = NativeArguments::isolate_offset();
148 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); 148 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
149 const intptr_t argv_offset = NativeArguments::argv_offset(); 149 const intptr_t argv_offset = NativeArguments::argv_offset();
150 const intptr_t retval_offset = NativeArguments::retval_offset(); 150 const intptr_t retval_offset = NativeArguments::retval_offset();
151 151
152 __ SetPrologueOffset(); 152 __ SetPrologueOffset();
153 __ TraceSimMsg("CallNativeCFunctionStub"); 153 __ Comment("CallNativeCFunctionStub");
154 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 154 __ addiu(SP, SP, Immediate(-3 * kWordSize));
155 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker 155 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker
156 __ sw(RA, Address(SP, 1 * kWordSize)); 156 __ sw(RA, Address(SP, 1 * kWordSize));
157 __ sw(FP, Address(SP, 0 * kWordSize)); 157 __ sw(FP, Address(SP, 0 * kWordSize));
158 __ mov(FP, SP); 158 __ mov(FP, SP);
159 159
160 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S6)) != 0); 160 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S6)) != 0);
161 __ LoadIsolate(S6); 161 __ LoadIsolate(S6);
162 162
163 // Save exit frame information to enable stack walking as we are about 163 // Save exit frame information to enable stack walking as we are about
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 // Call native wrapper function or redirection via simulator. 211 // Call native wrapper function or redirection via simulator.
212 #if defined(USING_SIMULATOR) 212 #if defined(USING_SIMULATOR)
213 uword entry = reinterpret_cast<uword>(NativeEntry::NativeCallWrapper); 213 uword entry = reinterpret_cast<uword>(NativeEntry::NativeCallWrapper);
214 entry = Simulator::RedirectExternalReference( 214 entry = Simulator::RedirectExternalReference(
215 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments); 215 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments);
216 __ LoadImmediate(T9, entry); 216 __ LoadImmediate(T9, entry);
217 __ jalr(T9); 217 __ jalr(T9);
218 #else 218 #else
219 __ BranchLink(&NativeEntry::NativeCallWrapperLabel()); 219 __ BranchLink(&NativeEntry::NativeCallWrapperLabel());
220 #endif 220 #endif
221 __ TraceSimMsg("CallNativeCFunctionStub return"); 221 __ Comment("CallNativeCFunctionStub return");
222 222
223 // Mark that the isolate is executing Dart code. 223 // Mark that the isolate is executing Dart code.
224 __ LoadImmediate(A2, VMTag::kDartTagId); 224 __ LoadImmediate(A2, VMTag::kDartTagId);
225 __ sw(A2, Address(S6, Isolate::vm_tag_offset())); 225 __ sw(A2, Address(S6, Isolate::vm_tag_offset()));
226 226
227 // Reset exit frame information in Isolate structure. 227 // Reset exit frame information in Isolate structure.
228 __ sw(ZR, Address(S6, Isolate::top_exit_frame_info_offset())); 228 __ sw(ZR, Address(S6, Isolate::top_exit_frame_info_offset()));
229 229
230 __ mov(SP, FP); 230 __ mov(SP, FP);
231 __ lw(RA, Address(SP, 1 * kWordSize)); 231 __ lw(RA, Address(SP, 1 * kWordSize));
232 __ lw(FP, Address(SP, 0 * kWordSize)); 232 __ lw(FP, Address(SP, 0 * kWordSize));
233 __ Ret(); 233 __ Ret();
234 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize)); 234 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize));
235 } 235 }
236 236
237 237
238 // Input parameters: 238 // Input parameters:
239 // RA : return address. 239 // RA : return address.
240 // SP : address of return value. 240 // SP : address of return value.
241 // T5 : address of the native function to call. 241 // T5 : address of the native function to call.
242 // A2 : address of first argument in argument array. 242 // A2 : address of first argument in argument array.
243 // A1 : argc_tag including number of arguments and function kind. 243 // A1 : argc_tag including number of arguments and function kind.
244 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { 244 void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) {
245 const intptr_t isolate_offset = NativeArguments::isolate_offset(); 245 const intptr_t isolate_offset = NativeArguments::isolate_offset();
246 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); 246 const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset();
247 const intptr_t argv_offset = NativeArguments::argv_offset(); 247 const intptr_t argv_offset = NativeArguments::argv_offset();
248 const intptr_t retval_offset = NativeArguments::retval_offset(); 248 const intptr_t retval_offset = NativeArguments::retval_offset();
249 249
250 __ SetPrologueOffset(); 250 __ SetPrologueOffset();
251 __ TraceSimMsg("CallNativeCFunctionStub"); 251 __ Comment("CallNativeCFunctionStub");
252 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 252 __ addiu(SP, SP, Immediate(-3 * kWordSize));
253 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker 253 __ sw(ZR, Address(SP, 2 * kWordSize)); // Push 0 for the PC marker
254 __ sw(RA, Address(SP, 1 * kWordSize)); 254 __ sw(RA, Address(SP, 1 * kWordSize));
255 __ sw(FP, Address(SP, 0 * kWordSize)); 255 __ sw(FP, Address(SP, 0 * kWordSize));
256 __ mov(FP, SP); 256 __ mov(FP, SP);
257 257
258 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S6)) != 0); 258 COMPILE_ASSERT((kAbiPreservedCpuRegs & (1 << S6)) != 0);
259 __ LoadIsolate(S6); 259 __ LoadIsolate(S6);
260 260
261 // Save exit frame information to enable stack walking as we are about 261 // Save exit frame information to enable stack walking as we are about
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 __ mov(A0, SP); // Pass the pointer to the NativeArguments. 304 __ mov(A0, SP); // Pass the pointer to the NativeArguments.
305 305
306 __ ReserveAlignedFrameSpace(kWordSize); // Just passing A0. 306 __ ReserveAlignedFrameSpace(kWordSize); // Just passing A0.
307 307
308 // Call native function or redirection via simulator. 308 // Call native function or redirection via simulator.
309 309
310 // We defensively always jalr through T9 because it is sometimes required by 310 // We defensively always jalr through T9 because it is sometimes required by
311 // the MIPS ABI. 311 // the MIPS ABI.
312 __ mov(T9, T5); 312 __ mov(T9, T5);
313 __ jalr(T9); 313 __ jalr(T9);
314 __ TraceSimMsg("CallNativeCFunctionStub return"); 314 __ Comment("CallNativeCFunctionStub return");
315 315
316 // Mark that the isolate is executing Dart code. 316 // Mark that the isolate is executing Dart code.
317 __ LoadImmediate(A2, VMTag::kDartTagId); 317 __ LoadImmediate(A2, VMTag::kDartTagId);
318 __ sw(A2, Address(S6, Isolate::vm_tag_offset())); 318 __ sw(A2, Address(S6, Isolate::vm_tag_offset()));
319 319
320 // Reset exit frame information in Isolate structure. 320 // Reset exit frame information in Isolate structure.
321 __ sw(ZR, Address(S6, Isolate::top_exit_frame_info_offset())); 321 __ sw(ZR, Address(S6, Isolate::top_exit_frame_info_offset()));
322 322
323 __ mov(SP, FP); 323 __ mov(SP, FP);
324 __ lw(RA, Address(SP, 1 * kWordSize)); 324 __ lw(RA, Address(SP, 1 * kWordSize));
325 __ lw(FP, Address(SP, 0 * kWordSize)); 325 __ lw(FP, Address(SP, 0 * kWordSize));
326 __ Ret(); 326 __ Ret();
327 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize)); 327 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize));
328 } 328 }
329 329
330 330
331 // Input parameters: 331 // Input parameters:
332 // S4: arguments descriptor array. 332 // S4: arguments descriptor array.
333 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) { 333 void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
334 __ TraceSimMsg("CallStaticFunctionStub"); 334 __ Comment("CallStaticFunctionStub");
335 __ EnterStubFrame(); 335 __ EnterStubFrame();
336 // Setup space on stack for return value and preserve arguments descriptor. 336 // Setup space on stack for return value and preserve arguments descriptor.
337 337
338 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 338 __ addiu(SP, SP, Immediate(-2 * kWordSize));
339 __ sw(S4, Address(SP, 1 * kWordSize)); 339 __ sw(S4, Address(SP, 1 * kWordSize));
340 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); 340 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
341 __ sw(TMP, Address(SP, 0 * kWordSize)); 341 __ sw(TMP, Address(SP, 0 * kWordSize));
342 342
343 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); 343 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
344 __ TraceSimMsg("CallStaticFunctionStub return"); 344 __ Comment("CallStaticFunctionStub return");
345 345
346 // Get Code object result and restore arguments descriptor array. 346 // Get Code object result and restore arguments descriptor array.
347 __ lw(T0, Address(SP, 0 * kWordSize)); 347 __ lw(T0, Address(SP, 0 * kWordSize));
348 __ lw(S4, Address(SP, 1 * kWordSize)); 348 __ lw(S4, Address(SP, 1 * kWordSize));
349 __ addiu(SP, SP, Immediate(2 * kWordSize)); 349 __ addiu(SP, SP, Immediate(2 * kWordSize));
350 350
351 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); 351 __ lw(T0, FieldAddress(T0, Code::instructions_offset()));
352 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); 352 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag);
353 353
354 // Remove the stub frame as we are about to jump to the dart function. 354 // Remove the stub frame as we are about to jump to the dart function.
355 __ LeaveStubFrameAndReturn(T0); 355 __ LeaveStubFrameAndReturn(T0);
356 } 356 }
357 357
358 358
359 // Called from a static call only when an invalid code has been entered 359 // Called from a static call only when an invalid code has been entered
360 // (invalid because its function was optimized or deoptimized). 360 // (invalid because its function was optimized or deoptimized).
361 // S4: arguments descriptor array. 361 // S4: arguments descriptor array.
362 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { 362 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
363 // Create a stub frame as we are pushing some objects on the stack before 363 // Create a stub frame as we are pushing some objects on the stack before
364 // calling into the runtime. 364 // calling into the runtime.
365 __ TraceSimMsg("FixCallersTarget"); 365 __ Comment("FixCallersTarget");
366 __ EnterStubFrame(); 366 __ EnterStubFrame();
367 // Setup space on stack for return value and preserve arguments descriptor. 367 // Setup space on stack for return value and preserve arguments descriptor.
368 __ addiu(SP, SP, Immediate(-2 * kWordSize)); 368 __ addiu(SP, SP, Immediate(-2 * kWordSize));
369 __ sw(S4, Address(SP, 1 * kWordSize)); 369 __ sw(S4, Address(SP, 1 * kWordSize));
370 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); 370 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
371 __ sw(TMP, Address(SP, 0 * kWordSize)); 371 __ sw(TMP, Address(SP, 0 * kWordSize));
372 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); 372 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
373 // Get Code object result and restore arguments descriptor array. 373 // Get Code object result and restore arguments descriptor array.
374 __ lw(T0, Address(SP, 0 * kWordSize)); 374 __ lw(T0, Address(SP, 0 * kWordSize));
375 __ lw(S4, Address(SP, 1 * kWordSize)); 375 __ lw(S4, Address(SP, 1 * kWordSize));
376 __ addiu(SP, SP, Immediate(2 * kWordSize)); 376 __ addiu(SP, SP, Immediate(2 * kWordSize));
377 377
378 // Jump to the dart function. 378 // Jump to the dart function.
379 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); 379 __ lw(T0, FieldAddress(T0, Code::instructions_offset()));
380 __ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag); 380 __ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag);
381 381
382 // Remove the stub frame. 382 // Remove the stub frame.
383 __ LeaveStubFrameAndReturn(T0); 383 __ LeaveStubFrameAndReturn(T0);
384 } 384 }
385 385
386 386
387 // Called from object allocate instruction when the allocation stub has been 387 // Called from object allocate instruction when the allocation stub has been
388 // disabled. 388 // disabled.
389 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { 389 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) {
390 __ TraceSimMsg("FixAllocationStubTarget"); 390 __ Comment("FixAllocationStubTarget");
391 __ EnterStubFrame(); 391 __ EnterStubFrame();
392 // Setup space on stack for return value. 392 // Setup space on stack for return value.
393 __ addiu(SP, SP, Immediate(-1 * kWordSize)); 393 __ addiu(SP, SP, Immediate(-1 * kWordSize));
394 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); 394 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
395 __ sw(TMP, Address(SP, 0 * kWordSize)); 395 __ sw(TMP, Address(SP, 0 * kWordSize));
396 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); 396 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
397 // Get Code object result. 397 // Get Code object result.
398 __ lw(T0, Address(SP, 0 * kWordSize)); 398 __ lw(T0, Address(SP, 0 * kWordSize));
399 __ addiu(SP, SP, Immediate(1 * kWordSize)); 399 __ addiu(SP, SP, Immediate(1 * kWordSize));
400 400
401 // Jump to the dart function. 401 // Jump to the dart function.
402 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); 402 __ lw(T0, FieldAddress(T0, Code::instructions_offset()));
403 __ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag); 403 __ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag);
404 404
405 // Remove the stub frame. 405 // Remove the stub frame.
406 __ LeaveStubFrameAndReturn(T0); 406 __ LeaveStubFrameAndReturn(T0);
407 } 407 }
408 408
409 409
410 // Called from array allocate instruction when the allocation stub has been 410 // Called from array allocate instruction when the allocation stub has been
411 // disabled. 411 // disabled.
412 // A0: element type (preserved). 412 // A0: element type (preserved).
413 // A1: length (preserved). 413 // A1: length (preserved).
414 void StubCode::GenerateFixAllocateArrayStubTargetStub(Assembler* assembler) { 414 void StubCode::GenerateFixAllocateArrayStubTargetStub(Assembler* assembler) {
415 __ TraceSimMsg("FixAllocationStubTarget"); 415 __ Comment("FixAllocationStubTarget");
416 __ EnterStubFrame(); 416 __ EnterStubFrame();
417 // Setup space on stack for return value. 417 // Setup space on stack for return value.
418 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 418 __ addiu(SP, SP, Immediate(-3 * kWordSize));
419 __ sw(A0, Address(SP, 2 * kWordSize)); 419 __ sw(A0, Address(SP, 2 * kWordSize));
420 __ sw(A1, Address(SP, 1 * kWordSize)); 420 __ sw(A1, Address(SP, 1 * kWordSize));
421 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); 421 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
422 __ sw(TMP, Address(SP, 0 * kWordSize)); 422 __ sw(TMP, Address(SP, 0 * kWordSize));
423 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); 423 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
424 // Get Code object result. 424 // Get Code object result.
425 __ lw(T0, Address(SP, 0 * kWordSize)); 425 __ lw(T0, Address(SP, 0 * kWordSize));
426 __ lw(A1, Address(SP, 1 * kWordSize)); 426 __ lw(A1, Address(SP, 1 * kWordSize));
427 __ lw(A0, Address(SP, 2 * kWordSize)); 427 __ lw(A0, Address(SP, 2 * kWordSize));
428 __ addiu(SP, SP, Immediate(3 * kWordSize)); 428 __ addiu(SP, SP, Immediate(3 * kWordSize));
429 429
430 // Jump to the dart function. 430 // Jump to the dart function.
431 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); 431 __ lw(T0, FieldAddress(T0, Code::instructions_offset()));
432 __ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag); 432 __ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag);
433 433
434 // Remove the stub frame. 434 // Remove the stub frame.
435 __ LeaveStubFrameAndReturn(T0); 435 __ LeaveStubFrameAndReturn(T0);
436 } 436 }
437 437
438 438
439 // Input parameters: 439 // Input parameters:
440 // A1: Smi-tagged argument count, may be zero. 440 // A1: Smi-tagged argument count, may be zero.
441 // FP[kParamEndSlotFromFp + 1]: Last argument. 441 // FP[kParamEndSlotFromFp + 1]: Last argument.
442 static void PushArgumentsArray(Assembler* assembler) { 442 static void PushArgumentsArray(Assembler* assembler) {
443 StubCode* stub_code = Isolate::Current()->stub_code(); 443 StubCode* stub_code = Isolate::Current()->stub_code();
444 __ TraceSimMsg("PushArgumentsArray"); 444 __ Comment("PushArgumentsArray");
445 // Allocate array to store arguments of caller. 445 // Allocate array to store arguments of caller.
446 __ LoadImmediate(A0, reinterpret_cast<intptr_t>(Object::null())); 446 __ LoadImmediate(A0, reinterpret_cast<intptr_t>(Object::null()));
447 // A0: Null element type for raw Array. 447 // A0: Null element type for raw Array.
448 // A1: Smi-tagged argument count, may be zero. 448 // A1: Smi-tagged argument count, may be zero.
449 const Code& array_stub = Code::Handle(stub_code->GetAllocateArrayStub()); 449 const Code& array_stub = Code::Handle(stub_code->GetAllocateArrayStub());
450 const ExternalLabel array_label(array_stub.EntryPoint()); 450 const ExternalLabel array_label(array_stub.EntryPoint());
451 __ BranchLink(&array_label); 451 __ BranchLink(&array_label);
452 __ TraceSimMsg("PushArgumentsArray return"); 452 __ Comment("PushArgumentsArray return");
453 // V0: newly allocated array. 453 // V0: newly allocated array.
454 // A1: Smi-tagged argument count, may be zero (was preserved by the stub). 454 // A1: Smi-tagged argument count, may be zero (was preserved by the stub).
455 __ Push(V0); // Array is in V0 and on top of stack. 455 __ Push(V0); // Array is in V0 and on top of stack.
456 __ sll(T1, A1, 1); 456 __ sll(T1, A1, 1);
457 __ addu(T1, FP, T1); 457 __ addu(T1, FP, T1);
458 __ AddImmediate(T1, kParamEndSlotFromFp * kWordSize); 458 __ AddImmediate(T1, kParamEndSlotFromFp * kWordSize);
459 // T1: address of first argument on stack. 459 // T1: address of first argument on stack.
460 // T2: address of first argument in array. 460 // T2: address of first argument in array.
461 461
462 Label loop, loop_exit; 462 Label loop, loop_exit;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 // 506 //
507 // Parts of the code cannot GC, part of the code can GC. 507 // Parts of the code cannot GC, part of the code can GC.
508 static void GenerateDeoptimizationSequence(Assembler* assembler, 508 static void GenerateDeoptimizationSequence(Assembler* assembler,
509 bool preserve_result) { 509 bool preserve_result) {
510 const intptr_t kPushedRegistersSize = 510 const intptr_t kPushedRegistersSize =
511 kNumberOfCpuRegisters * kWordSize + 511 kNumberOfCpuRegisters * kWordSize +
512 4 * kWordSize + // PP, FP, RA, PC marker. 512 4 * kWordSize + // PP, FP, RA, PC marker.
513 kNumberOfFRegisters * kWordSize; 513 kNumberOfFRegisters * kWordSize;
514 514
515 __ SetPrologueOffset(); 515 __ SetPrologueOffset();
516 __ TraceSimMsg("GenerateDeoptimizationSequence"); 516 __ Comment("GenerateDeoptimizationSequence");
517 // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there 517 // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
518 // is no need to set the correct PC marker or load PP, since they get patched. 518 // is no need to set the correct PC marker or load PP, since they get patched.
519 __ addiu(SP, SP, Immediate(-kPushedRegistersSize * kWordSize)); 519 __ addiu(SP, SP, Immediate(-kPushedRegistersSize * kWordSize));
520 __ sw(ZR, Address(SP, kPushedRegistersSize - 1 * kWordSize)); 520 __ sw(ZR, Address(SP, kPushedRegistersSize - 1 * kWordSize));
521 __ sw(RA, Address(SP, kPushedRegistersSize - 2 * kWordSize)); 521 __ sw(RA, Address(SP, kPushedRegistersSize - 2 * kWordSize));
522 __ sw(FP, Address(SP, kPushedRegistersSize - 3 * kWordSize)); 522 __ sw(FP, Address(SP, kPushedRegistersSize - 3 * kWordSize));
523 __ sw(PP, Address(SP, kPushedRegistersSize - 4 * kWordSize)); 523 __ sw(PP, Address(SP, kPushedRegistersSize - 4 * kWordSize));
524 __ addiu(FP, SP, Immediate(kPushedRegistersSize - 3 * kWordSize)); 524 __ addiu(FP, SP, Immediate(kPushedRegistersSize - 3 * kWordSize));
525 525
526 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry 526 // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 663
664 // Called for inline allocation of arrays. 664 // Called for inline allocation of arrays.
665 // Input parameters: 665 // Input parameters:
666 // RA: return address. 666 // RA: return address.
667 // A1: Array length as Smi (must be preserved). 667 // A1: Array length as Smi (must be preserved).
668 // A0: array element type (either NULL or an instantiated type). 668 // A0: array element type (either NULL or an instantiated type).
669 // NOTE: A1 cannot be clobbered here as the caller relies on it being saved. 669 // NOTE: A1 cannot be clobbered here as the caller relies on it being saved.
670 // The newly allocated object is returned in V0. 670 // The newly allocated object is returned in V0.
671 void StubCode::GeneratePatchableAllocateArrayStub(Assembler* assembler, 671 void StubCode::GeneratePatchableAllocateArrayStub(Assembler* assembler,
672 uword* entry_patch_offset, uword* patch_code_pc_offset) { 672 uword* entry_patch_offset, uword* patch_code_pc_offset) {
673 __ TraceSimMsg("AllocateArrayStub"); 673 __ Comment("AllocateArrayStub");
674 *entry_patch_offset = assembler->CodeSize(); 674 *entry_patch_offset = assembler->CodeSize();
675 Label slow_case; 675 Label slow_case;
676 676
677 // Compute the size to be allocated, it is based on the array length 677 // Compute the size to be allocated, it is based on the array length
678 // and is computed as: 678 // and is computed as:
679 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). 679 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
680 __ mov(T3, A1); // Array length. 680 __ mov(T3, A1); // Array length.
681 681
682 // Check that length is a positive Smi. 682 // Check that length is a positive Smi.
683 __ andi(CMPRES1, T3, Immediate(kSmiTagMask)); 683 __ andi(CMPRES1, T3, Immediate(kSmiTagMask));
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 // calling into the runtime. 786 // calling into the runtime.
787 __ EnterStubFrame(); 787 __ EnterStubFrame();
788 // Setup space on stack for return value. 788 // Setup space on stack for return value.
789 // Push array length as Smi and element type. 789 // Push array length as Smi and element type.
790 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 790 __ addiu(SP, SP, Immediate(-3 * kWordSize));
791 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); 791 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
792 __ sw(TMP, Address(SP, 2 * kWordSize)); 792 __ sw(TMP, Address(SP, 2 * kWordSize));
793 __ sw(A1, Address(SP, 1 * kWordSize)); 793 __ sw(A1, Address(SP, 1 * kWordSize));
794 __ sw(A0, Address(SP, 0 * kWordSize)); 794 __ sw(A0, Address(SP, 0 * kWordSize));
795 __ CallRuntime(kAllocateArrayRuntimeEntry, 2); 795 __ CallRuntime(kAllocateArrayRuntimeEntry, 2);
796 __ TraceSimMsg("AllocateArrayStub return"); 796 __ Comment("AllocateArrayStub return");
797 // Pop arguments; result is popped in IP. 797 // Pop arguments; result is popped in IP.
798 __ lw(V0, Address(SP, 2 * kWordSize)); 798 __ lw(V0, Address(SP, 2 * kWordSize));
799 __ lw(A1, Address(SP, 1 * kWordSize)); 799 __ lw(A1, Address(SP, 1 * kWordSize));
800 __ lw(A0, Address(SP, 0 * kWordSize)); 800 __ lw(A0, Address(SP, 0 * kWordSize));
801 __ addiu(SP, SP, Immediate(3 * kWordSize)); 801 __ addiu(SP, SP, Immediate(3 * kWordSize));
802 802
803 __ LeaveStubFrameAndReturn(); 803 __ LeaveStubFrameAndReturn();
804 *patch_code_pc_offset = assembler->CodeSize(); 804 *patch_code_pc_offset = assembler->CodeSize();
805 StubCode* stub_code = Isolate::Current()->stub_code(); 805 StubCode* stub_code = Isolate::Current()->stub_code();
806 __ BranchPatchable(&stub_code->FixAllocateArrayStubTargetLabel()); 806 __ BranchPatchable(&stub_code->FixAllocateArrayStubTargetLabel());
807 } 807 }
808 808
809 809
810 // Called when invoking Dart code from C++ (VM code). 810 // Called when invoking Dart code from C++ (VM code).
811 // Input parameters: 811 // Input parameters:
812 // RA : points to return address. 812 // RA : points to return address.
813 // A0 : entrypoint of the Dart function to call. 813 // A0 : entrypoint of the Dart function to call.
814 // A1 : arguments descriptor array. 814 // A1 : arguments descriptor array.
815 // A2 : arguments array. 815 // A2 : arguments array.
816 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) { 816 void StubCode::GenerateInvokeDartCodeStub(Assembler* assembler) {
817 // Save frame pointer coming in. 817 // Save frame pointer coming in.
818 __ TraceSimMsg("InvokeDartCodeStub"); 818 __ Comment("InvokeDartCodeStub");
819 __ EnterFrame(); 819 __ EnterFrame();
820 820
821 // Save new context and C++ ABI callee-saved registers. 821 // Save new context and C++ ABI callee-saved registers.
822 822
823 // The saved vm tag, top resource, and top exit frame info. 823 // The saved vm tag, top resource, and top exit frame info.
824 const intptr_t kPreservedSlots = 3; 824 const intptr_t kPreservedSlots = 3;
825 const intptr_t kPreservedRegSpace = 825 const intptr_t kPreservedRegSpace =
826 kWordSize * (kAbiPreservedCpuRegCount + kAbiPreservedFpuRegCount + 826 kWordSize * (kAbiPreservedCpuRegCount + kAbiPreservedFpuRegCount +
827 kPreservedSlots); 827 kPreservedSlots);
828 828
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 __ addiu(A1, A1, Immediate(1)); 894 __ addiu(A1, A1, Immediate(1));
895 __ BranchSignedLess(A1, T1, &push_arguments); 895 __ BranchSignedLess(A1, T1, &push_arguments);
896 __ delay_slot()->addiu(A2, A2, Immediate(kWordSize)); 896 __ delay_slot()->addiu(A2, A2, Immediate(kWordSize));
897 897
898 __ Bind(&done_push_arguments); 898 __ Bind(&done_push_arguments);
899 899
900 // Call the Dart code entrypoint. 900 // Call the Dart code entrypoint.
901 // We are calling into Dart code, here, so there is no need to call through 901 // We are calling into Dart code, here, so there is no need to call through
902 // T9 to match the ABI. 902 // T9 to match the ABI.
903 __ jalr(A0); // S4 is the arguments descriptor array. 903 __ jalr(A0); // S4 is the arguments descriptor array.
904 __ TraceSimMsg("InvokeDartCodeStub return"); 904 __ Comment("InvokeDartCodeStub return");
905 905
906 // Get rid of arguments pushed on the stack. 906 // Get rid of arguments pushed on the stack.
907 __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize); 907 __ AddImmediate(SP, FP, kExitLinkSlotFromEntryFp * kWordSize);
908 908
909 __ LoadIsolate(S6); 909 __ LoadIsolate(S6);
910 910
911 // Restore the current VMTag from the stack. 911 // Restore the current VMTag from the stack.
912 __ lw(T1, Address(SP, 2 * kWordSize)); 912 __ lw(T1, Address(SP, 2 * kWordSize));
913 __ sw(T1, Address(S6, Isolate::vm_tag_offset())); 913 __ sw(T1, Address(S6, Isolate::vm_tag_offset()));
914 914
(...skipping 26 matching lines...) Expand all
941 __ LeaveFrameAndReturn(); 941 __ LeaveFrameAndReturn();
942 } 942 }
943 943
944 944
945 // Called for inline allocation of contexts. 945 // Called for inline allocation of contexts.
946 // Input: 946 // Input:
947 // T1: number of context variables. 947 // T1: number of context variables.
948 // Output: 948 // Output:
949 // V0: new allocated RawContext object. 949 // V0: new allocated RawContext object.
950 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { 950 void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
951 __ TraceSimMsg("AllocateContext"); 951 __ Comment("AllocateContext");
952 if (FLAG_inline_alloc) { 952 if (FLAG_inline_alloc) {
953 Label slow_case; 953 Label slow_case;
954 Heap* heap = Isolate::Current()->heap(); 954 Heap* heap = Isolate::Current()->heap();
955 // First compute the rounded instance size. 955 // First compute the rounded instance size.
956 // T1: number of context variables. 956 // T1: number of context variables.
957 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1; 957 intptr_t fixed_size = sizeof(RawContext) + kObjectAlignment - 1;
958 __ LoadImmediate(T2, fixed_size); 958 __ LoadImmediate(T2, fixed_size);
959 __ sll(T0, T1, 2); 959 __ sll(T0, T1, 2);
960 __ addu(T2, T2, T0); 960 __ addu(T2, T2, T0);
961 ASSERT(kSmiTagShift == 1); 961 ASSERT(kSmiTagShift == 1);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 1060
1061 1061
1062 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate); 1062 DECLARE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate);
1063 1063
1064 1064
1065 // Helper stub to implement Assembler::StoreIntoObject. 1065 // Helper stub to implement Assembler::StoreIntoObject.
1066 // Input parameters: 1066 // Input parameters:
1067 // T0: Address (i.e. object) being stored into. 1067 // T0: Address (i.e. object) being stored into.
1068 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) { 1068 void StubCode::GenerateUpdateStoreBufferStub(Assembler* assembler) {
1069 // Save values being destroyed. 1069 // Save values being destroyed.
1070 __ TraceSimMsg("UpdateStoreBufferStub"); 1070 __ Comment("UpdateStoreBufferStub");
1071 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 1071 __ addiu(SP, SP, Immediate(-3 * kWordSize));
1072 __ sw(T3, Address(SP, 2 * kWordSize)); 1072 __ sw(T3, Address(SP, 2 * kWordSize));
1073 __ sw(T2, Address(SP, 1 * kWordSize)); 1073 __ sw(T2, Address(SP, 1 * kWordSize));
1074 __ sw(T1, Address(SP, 0 * kWordSize)); 1074 __ sw(T1, Address(SP, 0 * kWordSize));
1075 1075
1076 Label add_to_buffer; 1076 Label add_to_buffer;
1077 // Check whether this object has already been remembered. Skip adding to the 1077 // Check whether this object has already been remembered. Skip adding to the
1078 // store buffer if the object is in the store buffer already. 1078 // store buffer if the object is in the store buffer already.
1079 // Spilled: T1, T2, T3. 1079 // Spilled: T1, T2, T3.
1080 // T0: Address being stored. 1080 // T0: Address being stored.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize)); 1120 __ delay_slot()->addiu(SP, SP, Immediate(3 * kWordSize));
1121 __ Ret(); 1121 __ Ret();
1122 1122
1123 // Handle overflow: Call the runtime leaf function. 1123 // Handle overflow: Call the runtime leaf function.
1124 __ Bind(&L); 1124 __ Bind(&L);
1125 // Setup frame, push callee-saved registers. 1125 // Setup frame, push callee-saved registers.
1126 1126
1127 __ EnterCallRuntimeFrame(1 * kWordSize); 1127 __ EnterCallRuntimeFrame(1 * kWordSize);
1128 __ LoadIsolate(A0); 1128 __ LoadIsolate(A0);
1129 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1); 1129 __ CallRuntime(kStoreBufferBlockProcessRuntimeEntry, 1);
1130 __ TraceSimMsg("UpdateStoreBufferStub return"); 1130 __ Comment("UpdateStoreBufferStub return");
1131 // Restore callee-saved registers, tear down frame. 1131 // Restore callee-saved registers, tear down frame.
1132 __ LeaveCallRuntimeFrame(); 1132 __ LeaveCallRuntimeFrame();
1133 __ Ret(); 1133 __ Ret();
1134 } 1134 }
1135 1135
1136 1136
1137 // Called for inline allocation of objects. 1137 // Called for inline allocation of objects.
1138 // Input parameters: 1138 // Input parameters:
1139 // RA : return address. 1139 // RA : return address.
1140 // SP + 0 : type arguments object (only if class is parameterized). 1140 // SP + 0 : type arguments object (only if class is parameterized).
1141 // Returns patch_code_pc offset where patching code for disabling the stub 1141 // Returns patch_code_pc offset where patching code for disabling the stub
1142 // has been generated (similar to regularly generated Dart code). 1142 // has been generated (similar to regularly generated Dart code).
1143 void StubCode::GenerateAllocationStubForClass( 1143 void StubCode::GenerateAllocationStubForClass(
1144 Assembler* assembler, const Class& cls, 1144 Assembler* assembler, const Class& cls,
1145 uword* entry_patch_offset, uword* patch_code_pc_offset) { 1145 uword* entry_patch_offset, uword* patch_code_pc_offset) {
1146 __ TraceSimMsg("AllocationStubForClass"); 1146 __ Comment("AllocationStubForClass");
1147 *entry_patch_offset = assembler->CodeSize(); 1147 *entry_patch_offset = assembler->CodeSize();
1148 // The generated code is different if the class is parameterized. 1148 // The generated code is different if the class is parameterized.
1149 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; 1149 const bool is_cls_parameterized = cls.NumTypeArguments() > 0;
1150 ASSERT(!is_cls_parameterized || 1150 ASSERT(!is_cls_parameterized ||
1151 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); 1151 (cls.type_arguments_field_offset() != Class::kNoTypeArguments));
1152 // kInlineInstanceSize is a constant used as a threshold for determining 1152 // kInlineInstanceSize is a constant used as a threshold for determining
1153 // when the object initialization should be done as a loop or as 1153 // when the object initialization should be done as a loop or as
1154 // straight line code. 1154 // straight line code.
1155 const int kInlineInstanceSize = 12; 1155 const int kInlineInstanceSize = 12;
1156 const intptr_t instance_size = cls.instance_size(); 1156 const intptr_t instance_size = cls.instance_size();
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1252 __ sw(TMP, Address(SP, 1 * kWordSize)); // Class of object to be allocated. 1252 __ sw(TMP, Address(SP, 1 * kWordSize)); // Class of object to be allocated.
1253 1253
1254 if (is_cls_parameterized) { 1254 if (is_cls_parameterized) {
1255 // Push type arguments of object to be allocated and of instantiator. 1255 // Push type arguments of object to be allocated and of instantiator.
1256 __ sw(T1, Address(SP, 0 * kWordSize)); 1256 __ sw(T1, Address(SP, 0 * kWordSize));
1257 } else { 1257 } else {
1258 // Push null type arguments. 1258 // Push null type arguments.
1259 __ sw(T7, Address(SP, 0 * kWordSize)); 1259 __ sw(T7, Address(SP, 0 * kWordSize));
1260 } 1260 }
1261 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object. 1261 __ CallRuntime(kAllocateObjectRuntimeEntry, 2); // Allocate object.
1262 __ TraceSimMsg("AllocationStubForClass return"); 1262 __ Comment("AllocationStubForClass return");
1263 // Pop result (newly allocated object). 1263 // Pop result (newly allocated object).
1264 __ lw(V0, Address(SP, 2 * kWordSize)); 1264 __ lw(V0, Address(SP, 2 * kWordSize));
1265 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Pop arguments. 1265 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Pop arguments.
1266 // V0: new object 1266 // V0: new object
1267 // Restore the frame pointer and return. 1267 // Restore the frame pointer and return.
1268 __ LeaveStubFrameAndReturn(RA); 1268 __ LeaveStubFrameAndReturn(RA);
1269 *patch_code_pc_offset = assembler->CodeSize(); 1269 *patch_code_pc_offset = assembler->CodeSize();
1270 StubCode* stub_code = Isolate::Current()->stub_code(); 1270 StubCode* stub_code = Isolate::Current()->stub_code();
1271 __ BranchPatchable(&stub_code->FixAllocationStubTargetLabel()); 1271 __ BranchPatchable(&stub_code->FixAllocationStubTargetLabel());
1272 } 1272 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1305 // noSuchMethod on closures always throws an error, so it will never return. 1305 // noSuchMethod on closures always throws an error, so it will never return.
1306 __ break_(0); 1306 __ break_(0);
1307 } 1307 }
1308 1308
1309 1309
1310 // T0: function object. 1310 // T0: function object.
1311 // S5: inline cache data object. 1311 // S5: inline cache data object.
1312 // Cannot use function object from ICData as it may be the inlined 1312 // Cannot use function object from ICData as it may be the inlined
1313 // function and not the top-scope function. 1313 // function and not the top-scope function.
1314 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) { 1314 void StubCode::GenerateOptimizedUsageCounterIncrement(Assembler* assembler) {
1315 __ TraceSimMsg("OptimizedUsageCounterIncrement"); 1315 __ Comment("OptimizedUsageCounterIncrement");
1316 Register ic_reg = S5; 1316 Register ic_reg = S5;
1317 Register func_reg = T0; 1317 Register func_reg = T0;
1318 if (FLAG_trace_optimized_ic_calls) { 1318 if (FLAG_trace_optimized_ic_calls) {
1319 __ EnterStubFrame(); 1319 __ EnterStubFrame();
1320 __ addiu(SP, SP, Immediate(-4 * kWordSize)); 1320 __ addiu(SP, SP, Immediate(-4 * kWordSize));
1321 __ sw(T0, Address(SP, 3 * kWordSize)); 1321 __ sw(T0, Address(SP, 3 * kWordSize));
1322 __ sw(S5, Address(SP, 2 * kWordSize)); 1322 __ sw(S5, Address(SP, 2 * kWordSize));
1323 __ sw(ic_reg, Address(SP, 1 * kWordSize)); // Argument. 1323 __ sw(ic_reg, Address(SP, 1 * kWordSize)); // Argument.
1324 __ sw(func_reg, Address(SP, 0 * kWordSize)); // Argument. 1324 __ sw(func_reg, Address(SP, 0 * kWordSize)); // Argument.
1325 __ CallRuntime(kTraceICCallRuntimeEntry, 2); 1325 __ CallRuntime(kTraceICCallRuntimeEntry, 2);
1326 __ lw(S5, Address(SP, 2 * kWordSize)); 1326 __ lw(S5, Address(SP, 2 * kWordSize));
1327 __ lw(T0, Address(SP, 3 * kWordSize)); 1327 __ lw(T0, Address(SP, 3 * kWordSize));
1328 __ addiu(SP, SP, Immediate(4 * kWordSize)); // Discard argument; 1328 __ addiu(SP, SP, Immediate(4 * kWordSize)); // Discard argument;
1329 __ LeaveStubFrame(); 1329 __ LeaveStubFrame();
1330 } 1330 }
1331 __ lw(T7, FieldAddress(func_reg, Function::usage_counter_offset())); 1331 __ lw(T7, FieldAddress(func_reg, Function::usage_counter_offset()));
1332 __ addiu(T7, T7, Immediate(1)); 1332 __ addiu(T7, T7, Immediate(1));
1333 __ sw(T7, FieldAddress(func_reg, Function::usage_counter_offset())); 1333 __ sw(T7, FieldAddress(func_reg, Function::usage_counter_offset()));
1334 } 1334 }
1335 1335
1336 1336
1337 // Loads function into 'temp_reg'. 1337 // Loads function into 'temp_reg'.
1338 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, 1338 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler,
1339 Register temp_reg) { 1339 Register temp_reg) {
1340 __ TraceSimMsg("UsageCounterIncrement"); 1340 __ Comment("UsageCounterIncrement");
1341 Register ic_reg = S5; 1341 Register ic_reg = S5;
1342 Register func_reg = temp_reg; 1342 Register func_reg = temp_reg;
1343 ASSERT(temp_reg == T0); 1343 ASSERT(temp_reg == T0);
1344 __ Comment("Increment function counter"); 1344 __ Comment("Increment function counter");
1345 __ lw(func_reg, FieldAddress(ic_reg, ICData::owner_offset())); 1345 __ lw(func_reg, FieldAddress(ic_reg, ICData::owner_offset()));
1346 __ lw(T1, FieldAddress(func_reg, Function::usage_counter_offset())); 1346 __ lw(T1, FieldAddress(func_reg, Function::usage_counter_offset()));
1347 __ addiu(T1, T1, Immediate(1)); 1347 __ addiu(T1, T1, Immediate(1));
1348 __ sw(T1, FieldAddress(func_reg, Function::usage_counter_offset())); 1348 __ sw(T1, FieldAddress(func_reg, Function::usage_counter_offset()));
1349 } 1349 }
1350 1350
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1426 // - If receiver is not-Smi -> load receiver's class. 1426 // - If receiver is not-Smi -> load receiver's class.
1427 // - Check if 'num_args' (including receiver) match any IC data group. 1427 // - Check if 'num_args' (including receiver) match any IC data group.
1428 // - Match found -> jump to target. 1428 // - Match found -> jump to target.
1429 // - Match not found -> jump to IC miss. 1429 // - Match not found -> jump to IC miss.
1430 void StubCode::GenerateNArgsCheckInlineCacheStub( 1430 void StubCode::GenerateNArgsCheckInlineCacheStub(
1431 Assembler* assembler, 1431 Assembler* assembler,
1432 intptr_t num_args, 1432 intptr_t num_args,
1433 const RuntimeEntry& handle_ic_miss, 1433 const RuntimeEntry& handle_ic_miss,
1434 Token::Kind kind, 1434 Token::Kind kind,
1435 RangeCollectionMode range_collection_mode) { 1435 RangeCollectionMode range_collection_mode) {
1436 __ TraceSimMsg("NArgsCheckInlineCacheStub"); 1436 __ Comment("NArgsCheckInlineCacheStub");
1437 ASSERT(num_args > 0); 1437 ASSERT(num_args > 0);
1438 #if defined(DEBUG) 1438 #if defined(DEBUG)
1439 { Label ok; 1439 { Label ok;
1440 // Check that the IC data array has NumArgsTested() == num_args. 1440 // Check that the IC data array has NumArgsTested() == num_args.
1441 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. 1441 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
1442 __ lw(T0, FieldAddress(S5, ICData::state_bits_offset())); 1442 __ lw(T0, FieldAddress(S5, ICData::state_bits_offset()));
1443 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. 1443 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed.
1444 __ andi(T0, T0, Immediate(ICData::NumArgsTestedMask())); 1444 __ andi(T0, T0, Immediate(ICData::NumArgsTestedMask()));
1445 __ BranchEqual(T0, Immediate(num_args), &ok); 1445 __ BranchEqual(T0, Immediate(num_args), &ok);
1446 __ Stop("Incorrect stub for IC data"); 1446 __ Stop("Incorrect stub for IC data");
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1565 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); 1565 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
1566 __ sw(TMP, Address(SP, (num_slots - 3) * kWordSize)); 1566 __ sw(TMP, Address(SP, (num_slots - 3) * kWordSize));
1567 // Push call arguments. 1567 // Push call arguments.
1568 for (intptr_t i = 0; i < num_args; i++) { 1568 for (intptr_t i = 0; i < num_args; i++) {
1569 __ lw(TMP, Address(T1, -i * kWordSize)); 1569 __ lw(TMP, Address(T1, -i * kWordSize));
1570 __ sw(TMP, Address(SP, (num_slots - i - 4) * kWordSize)); 1570 __ sw(TMP, Address(SP, (num_slots - i - 4) * kWordSize));
1571 } 1571 }
1572 // Pass IC data object. 1572 // Pass IC data object.
1573 __ sw(S5, Address(SP, (num_slots - num_args - 4) * kWordSize)); 1573 __ sw(S5, Address(SP, (num_slots - num_args - 4) * kWordSize));
1574 __ CallRuntime(handle_ic_miss, num_args + 1); 1574 __ CallRuntime(handle_ic_miss, num_args + 1);
1575 __ TraceSimMsg("NArgsCheckInlineCacheStub return"); 1575 __ Comment("NArgsCheckInlineCacheStub return");
1576 // Pop returned function object into T3. 1576 // Pop returned function object into T3.
1577 // Restore arguments descriptor array and IC data array. 1577 // Restore arguments descriptor array and IC data array.
1578 __ lw(T3, Address(SP, (num_slots - 3) * kWordSize)); 1578 __ lw(T3, Address(SP, (num_slots - 3) * kWordSize));
1579 __ lw(S4, Address(SP, (num_slots - 2) * kWordSize)); 1579 __ lw(S4, Address(SP, (num_slots - 2) * kWordSize));
1580 __ lw(S5, Address(SP, (num_slots - 1) * kWordSize)); 1580 __ lw(S5, Address(SP, (num_slots - 1) * kWordSize));
1581 // Remove the call arguments pushed earlier, including the IC data object 1581 // Remove the call arguments pushed earlier, including the IC data object
1582 // and the arguments descriptor array. 1582 // and the arguments descriptor array.
1583 __ addiu(SP, SP, Immediate(num_slots * kWordSize)); 1583 __ addiu(SP, SP, Immediate(num_slots * kWordSize));
1584 __ LeaveStubFrame(); 1584 __ LeaveStubFrame();
1585 1585
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1753 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL, 1753 kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL,
1754 kIgnoreRanges); 1754 kIgnoreRanges);
1755 } 1755 }
1756 1756
1757 1757
1758 // Intermediary stub between a static call and its target. ICData contains 1758 // Intermediary stub between a static call and its target. ICData contains
1759 // the target function and the call count. 1759 // the target function and the call count.
1760 // S5: ICData 1760 // S5: ICData
1761 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { 1761 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) {
1762 GenerateUsageCounterIncrement(assembler, T0); 1762 GenerateUsageCounterIncrement(assembler, T0);
1763 __ TraceSimMsg("UnoptimizedStaticCallStub"); 1763 __ Comment("UnoptimizedStaticCallStub");
1764 #if defined(DEBUG) 1764 #if defined(DEBUG)
1765 { Label ok; 1765 { Label ok;
1766 // Check that the IC data array has NumArgsTested() == 0. 1766 // Check that the IC data array has NumArgsTested() == 0.
1767 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. 1767 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'.
1768 __ lw(T0, FieldAddress(S5, ICData::state_bits_offset())); 1768 __ lw(T0, FieldAddress(S5, ICData::state_bits_offset()));
1769 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. 1769 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed.
1770 __ andi(T0, T0, Immediate(ICData::NumArgsTestedMask())); 1770 __ andi(T0, T0, Immediate(ICData::NumArgsTestedMask()));
1771 __ beq(T0, ZR, &ok); 1771 __ beq(T0, ZR, &ok);
1772 __ Stop("Incorrect IC data for unoptimized static call"); 1772 __ Stop("Incorrect IC data for unoptimized static call");
1773 __ Bind(&ok); 1773 __ Bind(&ok);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1945 } 1945 }
1946 1946
1947 1947
1948 // Used to check class and type arguments. Arguments passed in registers: 1948 // Used to check class and type arguments. Arguments passed in registers:
1949 // RA: return address. 1949 // RA: return address.
1950 // A0: instance (must be preserved). 1950 // A0: instance (must be preserved).
1951 // A1: instantiator type arguments or NULL. 1951 // A1: instantiator type arguments or NULL.
1952 // A2: cache array. 1952 // A2: cache array.
1953 // Result in V0: null -> not found, otherwise result (true or false). 1953 // Result in V0: null -> not found, otherwise result (true or false).
1954 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { 1954 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) {
1955 __ TraceSimMsg("SubtypeNTestCacheStub"); 1955 __ Comment("SubtypeNTestCacheStub");
1956 ASSERT((1 <= n) && (n <= 3)); 1956 ASSERT((1 <= n) && (n <= 3));
1957 if (n > 1) { 1957 if (n > 1) {
1958 // Get instance type arguments. 1958 // Get instance type arguments.
1959 __ LoadClass(T0, A0); 1959 __ LoadClass(T0, A0);
1960 // Compute instance type arguments into T1. 1960 // Compute instance type arguments into T1.
1961 Label has_no_type_arguments; 1961 Label has_no_type_arguments;
1962 __ LoadImmediate(T1, reinterpret_cast<intptr_t>(Object::null())); 1962 __ LoadImmediate(T1, reinterpret_cast<intptr_t>(Object::null()));
1963 __ lw(T2, FieldAddress(T0, 1963 __ lw(T2, FieldAddress(T0,
1964 Class::type_arguments_field_offset_in_words_offset())); 1964 Class::type_arguments_field_offset_in_words_offset()));
1965 __ BranchEqual( 1965 __ BranchEqual(
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
2088 2088
2089 __ jr(A0); // Jump to the exception handler code. 2089 __ jr(A0); // Jump to the exception handler code.
2090 __ delay_slot()->mov(SP, A1); // Stack pointer. 2090 __ delay_slot()->mov(SP, A1); // Stack pointer.
2091 } 2091 }
2092 2092
2093 2093
2094 // Calls to the runtime to optimize the given function. 2094 // Calls to the runtime to optimize the given function.
2095 // T0: function to be reoptimized. 2095 // T0: function to be reoptimized.
2096 // S4: argument descriptor (preserved). 2096 // S4: argument descriptor (preserved).
2097 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { 2097 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
2098 __ TraceSimMsg("OptimizeFunctionStub"); 2098 __ Comment("OptimizeFunctionStub");
2099 __ EnterStubFrame(); 2099 __ EnterStubFrame();
2100 __ addiu(SP, SP, Immediate(-3 * kWordSize)); 2100 __ addiu(SP, SP, Immediate(-3 * kWordSize));
2101 __ sw(S4, Address(SP, 2 * kWordSize)); 2101 __ sw(S4, Address(SP, 2 * kWordSize));
2102 // Setup space on stack for return value. 2102 // Setup space on stack for return value.
2103 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); 2103 __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null()));
2104 __ sw(TMP, Address(SP, 1 * kWordSize)); 2104 __ sw(TMP, Address(SP, 1 * kWordSize));
2105 __ sw(T0, Address(SP, 0 * kWordSize)); 2105 __ sw(T0, Address(SP, 0 * kWordSize));
2106 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); 2106 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
2107 __ TraceSimMsg("OptimizeFunctionStub return"); 2107 __ Comment("OptimizeFunctionStub return");
2108 __ lw(T0, Address(SP, 1 * kWordSize)); // Get Code object 2108 __ lw(T0, Address(SP, 1 * kWordSize)); // Get Code object
2109 __ lw(S4, Address(SP, 2 * kWordSize)); // Restore argument descriptor. 2109 __ lw(S4, Address(SP, 2 * kWordSize)); // Restore argument descriptor.
2110 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Discard argument. 2110 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Discard argument.
2111 2111
2112 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); 2112 __ lw(T0, FieldAddress(T0, Code::instructions_offset()));
2113 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); 2113 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag);
2114 __ LeaveStubFrameAndReturn(T0); 2114 __ LeaveStubFrameAndReturn(T0);
2115 __ break_(0); 2115 __ break_(0);
2116 } 2116 }
2117 2117
2118 2118
2119 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, 2119 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t,
2120 BigintCompare, 2120 BigintCompare,
2121 RawBigint* left, 2121 RawBigint* left,
2122 RawBigint* right); 2122 RawBigint* right);
2123 2123
2124 2124
2125 // Does identical check (object references are equal or not equal) with special 2125 // Does identical check (object references are equal or not equal) with special
2126 // checks for boxed numbers. 2126 // checks for boxed numbers.
2127 // Returns: CMPRES1 is zero if equal, non-zero otherwise. 2127 // Returns: CMPRES1 is zero if equal, non-zero otherwise.
2128 // Note: A Mint cannot contain a value that would fit in Smi, a Bigint 2128 // Note: A Mint cannot contain a value that would fit in Smi, a Bigint
2129 // cannot contain a value that fits in Mint or Smi. 2129 // cannot contain a value that fits in Mint or Smi.
2130 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler, 2130 void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler,
2131 const Register left, 2131 const Register left,
2132 const Register right, 2132 const Register right,
2133 const Register temp1, 2133 const Register temp1,
2134 const Register temp2) { 2134 const Register temp2) {
2135 __ TraceSimMsg("IdenticalWithNumberCheckStub");
2136 __ Comment("IdenticalWithNumberCheckStub"); 2135 __ Comment("IdenticalWithNumberCheckStub");
2137 Label reference_compare, done, check_mint, check_bigint; 2136 Label reference_compare, done, check_mint, check_bigint;
2138 // If any of the arguments is Smi do reference compare. 2137 // If any of the arguments is Smi do reference compare.
2139 __ andi(temp1, left, Immediate(kSmiTagMask)); 2138 __ andi(temp1, left, Immediate(kSmiTagMask));
2140 __ beq(temp1, ZR, &reference_compare); 2139 __ beq(temp1, ZR, &reference_compare);
2141 __ andi(temp1, right, Immediate(kSmiTagMask)); 2140 __ andi(temp1, right, Immediate(kSmiTagMask));
2142 __ beq(temp1, ZR, &reference_compare); 2141 __ beq(temp1, ZR, &reference_compare);
2143 2142
2144 // Value compare for two doubles. 2143 // Value compare for two doubles.
2145 __ LoadImmediate(temp1, kDoubleCid); 2144 __ LoadImmediate(temp1, kDoubleCid);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2184 __ subu(CMPRES1, temp1, temp2); 2183 __ subu(CMPRES1, temp1, temp2);
2185 __ bne(CMPRES1, ZR, &done); 2184 __ bne(CMPRES1, ZR, &done);
2186 2185
2187 __ EnterStubFrame(); 2186 __ EnterStubFrame();
2188 __ ReserveAlignedFrameSpace(2 * kWordSize); 2187 __ ReserveAlignedFrameSpace(2 * kWordSize);
2189 __ sw(left, Address(SP, 1 * kWordSize)); 2188 __ sw(left, Address(SP, 1 * kWordSize));
2190 __ sw(right, Address(SP, 0 * kWordSize)); 2189 __ sw(right, Address(SP, 0 * kWordSize));
2191 __ mov(A0, left); 2190 __ mov(A0, left);
2192 __ mov(A1, right); 2191 __ mov(A1, right);
2193 __ CallRuntime(kBigintCompareRuntimeEntry, 2); 2192 __ CallRuntime(kBigintCompareRuntimeEntry, 2);
2194 __ TraceSimMsg("IdenticalWithNumberCheckStub return"); 2193 __ Comment("IdenticalWithNumberCheckStub return");
2195 // Result in V0, 0 means equal. 2194 // Result in V0, 0 means equal.
2196 __ LeaveStubFrame(); 2195 __ LeaveStubFrame();
2197 __ b(&done); 2196 __ b(&done);
2198 __ delay_slot()->mov(CMPRES1, V0); 2197 __ delay_slot()->mov(CMPRES1, V0);
2199 2198
2200 __ Bind(&reference_compare); 2199 __ Bind(&reference_compare);
2201 __ subu(CMPRES1, left, right); 2200 __ subu(CMPRES1, left, right);
2202 __ Bind(&done); 2201 __ Bind(&done);
2203 // A branch or test after this comparison will check CMPRES1 == ZR. 2202 // A branch or test after this comparison will check CMPRES1 == ZR.
2204 } 2203 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2252 const Register right = T0; 2251 const Register right = T0;
2253 __ lw(left, Address(SP, 1 * kWordSize)); 2252 __ lw(left, Address(SP, 1 * kWordSize));
2254 __ lw(right, Address(SP, 0 * kWordSize)); 2253 __ lw(right, Address(SP, 0 * kWordSize));
2255 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); 2254 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2);
2256 __ Ret(); 2255 __ Ret();
2257 } 2256 }
2258 2257
2259 } // namespace dart 2258 } // namespace dart
2260 2259
2261 #endif // defined TARGET_ARCH_MIPS 2260 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698