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

Side by Side Diff: src/macro-assembler-arm.cc

Issue 1930: Adapt to new calling convention on ARM. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 12 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/macro-assembler-arm.h ('k') | src/macro-assembler-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 242
243 ldr(scratch, MemOperand(object)); 243 ldr(scratch, MemOperand(object));
244 mov(ip, Operand(1)); 244 mov(ip, Operand(1));
245 orr(scratch, scratch, Operand(ip, LSL, offset)); 245 orr(scratch, scratch, Operand(ip, LSL, offset));
246 str(scratch, MemOperand(object)); 246 str(scratch, MemOperand(object));
247 247
248 bind(&done); 248 bind(&done);
249 } 249 }
250 250
251 251
252 void MacroAssembler::EnterJSFrame(int argc) { 252 void MacroAssembler::EnterInternalFrame() {
253 // Generate code entering a JS function called from a JS function 253 // r0-r3: preserved
254 // stack: receiver, arguments 254 int type = StackFrame::INTERNAL;
255 // r0: number of arguments (not including function, nor receiver)
256 // r1: preserved
257 // sp: stack pointer
258 // fp: frame pointer
259 // cp: callee's context
260 // pp: caller's parameter pointer
261 // lr: return address
262 255
263 // compute parameter pointer before making changes 256 stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
264 // ip = sp + kPointerSize*(args_len+1); // +1 for receiver 257 mov(ip, Operand(Smi::FromInt(type)));
265 add(ip, sp, Operand(r0, LSL, kPointerSizeLog2)); 258 push(ip);
266 add(ip, ip, Operand(kPointerSize)); 259 mov(ip, Operand(0));
267 260 push(ip); // Push an empty code cache slot.
268 // push extra parameters if we don't have enough 261 add(fp, sp, Operand(3 * kPointerSize)); // Adjust FP to point to saved FP.
269 // (this can only happen if argc > 0 to begin with)
270 if (argc > 0) {
271 Label loop, done;
272
273 // assume enough arguments to be the most common case
274 sub(r2, r0, Operand(argc), SetCC); // number of missing arguments
275 b(ge, &done); // enough arguments
276
277 // not enough arguments
278 mov(r3, Operand(Factory::undefined_value()));
279 bind(&loop);
280 push(r3);
281 add(r2, r2, Operand(1), SetCC);
282 b(lt, &loop);
283
284 bind(&done);
285 }
286
287 mov(r3, Operand(r0)); // args_len to be saved
288 mov(r2, Operand(cp)); // context to be saved
289
290 // push in reverse order: context (r2), args_len (r3), caller_pp, caller_fp,
291 // sp_on_exit (ip == pp, may be patched on exit), return address
292 stm(db_w, sp, r2.bit() | r3.bit() | pp.bit() | fp.bit() |
293 ip.bit() | lr.bit());
294
295 // Setup new frame pointer.
296 add(fp, sp, Operand(-StandardFrameConstants::kContextOffset));
297 mov(pp, Operand(ip)); // setup new parameter pointer
298 mov(r0, Operand(0)); // spare slot to store caller code object during GC
299 push(r0);
300 // r1: preserved
301 } 262 }
302 263
303 264
304 void MacroAssembler::ExitJSFrame(ExitJSFlag flag) { 265 void MacroAssembler::ExitInternalFrame() {
305 // r0: result 266 // r0: preserved
306 // sp: stack pointer 267 // r1: preserved
307 // fp: frame pointer 268 // r2: preserved
308 // pp: parameter pointer
309 269
310 if (flag == DO_NOT_RETURN) { 270 // Drop the execution stack down to the frame pointer and restore the caller
311 add(r3, fp, Operand(JavaScriptFrameConstants::kSavedRegistersOffset)); 271 // frame pointer and return address.
312 } 272 mov(sp, fp);
313 273 ldm(ia_w, sp, fp.bit() | lr.bit());
314 if (flag == DO_NOT_RETURN) {
315 // restore sp as caller_sp (not as pp)
316 str(r3, MemOperand(fp, JavaScriptFrameConstants::kSPOnExitOffset));
317 }
318
319 if (flag == DO_NOT_RETURN && generating_stub()) {
320 // If we're generating a stub, we need to preserve the link
321 // register to be able to return to the place the stub was called
322 // from.
323 mov(ip, Operand(lr));
324 }
325
326 mov(sp, Operand(fp)); // respect ABI stack constraint
327 ldm(ia, sp, pp.bit() | fp.bit() | sp.bit() |
328 ((flag == RETURN) ? pc.bit() : lr.bit()));
329
330 if (flag == DO_NOT_RETURN && generating_stub()) {
331 // Return to the place where the stub was called without
332 // clobbering the value of the link register.
333 mov(pc, Operand(ip));
334 }
335
336 // r0: result
337 // sp: points to function arg (if return) or to last arg (if no return)
338 // fp: restored frame pointer
339 // pp: restored parameter pointer
340 } 274 }
341 275
342 276
343 void MacroAssembler::InvokePrologue(const ParameterCount& expected, 277 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
344 const ParameterCount& actual, 278 const ParameterCount& actual,
345 Handle<Code> code_constant, 279 Handle<Code> code_constant,
346 Register code_reg, 280 Register code_reg,
347 Label* done, 281 Label* done,
348 InvokeFlag flag) { 282 InvokeFlag flag) {
349 if (actual.is_immediate()) { 283 bool definitely_matches = false;
350 mov(r0, Operand(actual.immediate())); // Push the number of arguments. 284 Label regular_invoke;
285
286 // Check whether the expected and actual arguments count match. If not,
287 // setup registers according to contract with ArgumentsAdaptorTrampoline:
288 // r0: actual arguments count
289 // r1: function (passed through to callee)
290 // r2: expected arguments count
291 // r3: callee code entry
292
293 // The code below is made a lot easier because the calling code already sets
294 // up actual and expected registers according to the contract if values are
295 // passed in registers.
296 ASSERT(actual.is_immediate() || actual.reg().is(r0));
297 ASSERT(expected.is_immediate() || expected.reg().is(r2));
298 ASSERT((!code_constant.is_null() && code_reg.is(no_reg)) || code_reg.is(r3));
299
300 if (expected.is_immediate()) {
301 ASSERT(actual.is_immediate());
302 if (expected.immediate() == actual.immediate()) {
303 definitely_matches = true;
304 } else {
305 mov(r0, Operand(actual.immediate()));
306 mov(r2, Operand(expected.immediate()));
307 }
351 } else { 308 } else {
352 if (!actual.reg().is(r0)) { 309 if (actual.is_immediate()) {
353 mov(r0, Operand(actual.reg())); 310 cmp(expected.reg(), Operand(actual.immediate()));
311 b(eq, &regular_invoke);
312 mov(r0, Operand(actual.immediate()));
313 } else {
314 cmp(expected.reg(), Operand(actual.reg()));
315 b(eq, &regular_invoke);
354 } 316 }
355 } 317 }
318
319 if (!definitely_matches) {
320 if (!code_constant.is_null()) {
321 mov(r3, Operand(code_constant));
322 add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
323 }
324
325 Handle<Code> adaptor =
326 Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
327 if (flag == CALL_FUNCTION) {
328 Call(adaptor, code_target);
329 b(done);
330 } else {
331 Jump(adaptor, code_target);
332 }
333 bind(&regular_invoke);
334 }
356 } 335 }
357 336
358 337
359 void MacroAssembler::InvokeCode(Register code, 338 void MacroAssembler::InvokeCode(Register code,
360 const ParameterCount& expected, 339 const ParameterCount& expected,
361 const ParameterCount& actual, 340 const ParameterCount& actual,
362 InvokeFlag flag) { 341 InvokeFlag flag) {
363 Label done; 342 Label done;
364 343
365 InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag); 344 InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag);
(...skipping 29 matching lines...) Expand all
395 bind(&done); 374 bind(&done);
396 } 375 }
397 376
398 377
399 void MacroAssembler::InvokeFunction(Register fun, 378 void MacroAssembler::InvokeFunction(Register fun,
400 const ParameterCount& actual, 379 const ParameterCount& actual,
401 InvokeFlag flag) { 380 InvokeFlag flag) {
402 // Contract with called JS functions requires that function is passed in r1. 381 // Contract with called JS functions requires that function is passed in r1.
403 ASSERT(fun.is(r1)); 382 ASSERT(fun.is(r1));
404 383
384 Register expected_reg = r2;
405 Register code_reg = r3; 385 Register code_reg = r3;
406 Register expected_reg = r2;
407
408 // Make sure that the code and expected registers do not collide with the
409 // actual register being passed in.
410 if (actual.is_reg()) {
411 if (actual.reg().is(code_reg)) {
412 code_reg = r4;
413 } else if (actual.reg().is(expected_reg)) {
414 expected_reg = r4;
415 }
416 }
417 386
418 ldr(code_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 387 ldr(code_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
419 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 388 ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
420 ldr(expected_reg, 389 ldr(expected_reg,
421 FieldMemOperand(code_reg, 390 FieldMemOperand(code_reg,
422 SharedFunctionInfo::kFormalParameterCountOffset)); 391 SharedFunctionInfo::kFormalParameterCountOffset));
423 ldr(code_reg, 392 ldr(code_reg,
424 MemOperand(code_reg, SharedFunctionInfo::kCodeOffset - kHeapObjectTag)); 393 MemOperand(code_reg, SharedFunctionInfo::kCodeOffset - kHeapObjectTag));
425 add(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag)); 394 add(code_reg, code_reg, Operand(Code::kHeaderSize - kHeapObjectTag));
426 395
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 mov(r3, Operand(StackHandler::TRY_FINALLY)); 469 mov(r3, Operand(StackHandler::TRY_FINALLY));
501 } 470 }
502 push(r3); // state 471 push(r3); // state
503 mov(r3, Operand(ExternalReference(Top::k_handler_address))); 472 mov(r3, Operand(ExternalReference(Top::k_handler_address)));
504 ldr(r1, MemOperand(r3)); 473 ldr(r1, MemOperand(r3));
505 push(r1); // next sp 474 push(r1); // next sp
506 str(sp, MemOperand(r3)); // chain handler 475 str(sp, MemOperand(r3)); // chain handler
507 mov(r0, Operand(Smi::FromInt(StackHandler::kCodeNotPresent))); // new TOS 476 mov(r0, Operand(Smi::FromInt(StackHandler::kCodeNotPresent))); // new TOS
508 push(r0); 477 push(r0);
509 } else { 478 } else {
510 // Must preserve r0-r3, r5-r7 are available. 479 // Must preserve r0-r4, r5-r7 are available.
511 ASSERT(try_location == IN_JS_ENTRY); 480 ASSERT(try_location == IN_JS_ENTRY);
512 // The parameter pointer is meaningless here and fp does not point to a JS 481 // The parameter pointer is meaningless here and fp does not point to a JS
513 // frame. So we save NULL for both pp and fp. We expect the code throwing an 482 // frame. So we save NULL for both pp and fp. We expect the code throwing an
514 // exception to check fp before dereferencing it to restore the context. 483 // exception to check fp before dereferencing it to restore the context.
515 mov(pp, Operand(0)); // set pp to NULL 484 mov(pp, Operand(0)); // set pp to NULL
516 mov(ip, Operand(0)); // to save a NULL fp 485 mov(ip, Operand(0)); // to save a NULL fp
517 stm(db_w, sp, pp.bit() | ip.bit() | lr.bit()); 486 stm(db_w, sp, pp.bit() | ip.bit() | lr.bit());
518 mov(r6, Operand(StackHandler::ENTRY)); 487 mov(r6, Operand(StackHandler::ENTRY));
519 push(r6); // state 488 push(r6); // state
520 mov(r7, Operand(ExternalReference(Top::k_handler_address))); 489 mov(r7, Operand(ExternalReference(Top::k_handler_address)));
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
681 #if defined(__thumb__) 650 #if defined(__thumb__)
682 // Thumb mode builtin. 651 // Thumb mode builtin.
683 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1); 652 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1);
684 #endif 653 #endif
685 mov(r1, Operand(builtin)); 654 mov(r1, Operand(builtin));
686 CEntryStub stub; 655 CEntryStub stub;
687 Jump(stub.GetCode(), code_target); 656 Jump(stub.GetCode(), code_target);
688 } 657 }
689 658
690 659
691 void MacroAssembler::InvokeBuiltin(const char* name, 660 Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id,
692 int argc, 661 bool* resolved) {
662 // Contract with compiled functions is that the function is passed in r1.
663 int builtins_offset =
664 JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
665 ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
666 ldr(r1, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset));
667 ldr(r1, FieldMemOperand(r1, builtins_offset));
668
669 return Builtins::GetCode(id, resolved);
670 }
671
672
673 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
693 InvokeJSFlags flags) { 674 InvokeJSFlags flags) {
694 Handle<String> symbol = Factory::LookupAsciiSymbol(name); 675 bool resolved;
695 Object* object = Top::security_context_builtins()->GetProperty(*symbol); 676 Handle<Code> code = ResolveBuiltin(id, &resolved);
696 bool unresolved = true;
697 Code* code = Builtins::builtin(Builtins::Illegal);
698 677
699 if (object->IsJSFunction()) { 678 if (flags == CALL_JS) {
700 Handle<JSFunction> function(JSFunction::cast(object)); 679 Call(code, code_target);
701 if (function->is_compiled() || CompileLazy(function, CLEAR_EXCEPTION)) { 680 } else {
702 code = function->code(); 681 ASSERT(flags == JUMP_JS);
703 unresolved = false; 682 Jump(code, code_target);
704 }
705 } 683 }
706 684
707 if (flags == CALL_JS) { 685 if (!resolved) {
708 Call(Handle<Code>(code), code_target); 686 const char* name = Builtins::GetName(id);
709 } else { 687 int argc = Builtins::GetArgumentsCount(id);
710 ASSERT(flags == JUMP_JS);
711 Jump(Handle<Code>(code), code_target);
712 }
713
714 if (unresolved) {
715 uint32_t flags = 688 uint32_t flags =
716 Bootstrapper::FixupFlagsArgumentsCount::encode(argc) | 689 Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
717 Bootstrapper::FixupFlagsIsPCRelative::encode(false); 690 Bootstrapper::FixupFlagsIsPCRelative::encode(true);
691 Unresolved entry = { pc_offset() - sizeof(Instr), flags, name };
692 unresolved_.Add(entry);
693 }
694 }
695
696
697 void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
698 bool resolved;
699 Handle<Code> code = ResolveBuiltin(id, &resolved);
700
701 mov(target, Operand(code));
702 if (!resolved) {
703 const char* name = Builtins::GetName(id);
704 int argc = Builtins::GetArgumentsCount(id);
705 uint32_t flags =
706 Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
707 Bootstrapper::FixupFlagsIsPCRelative::encode(true);
718 Unresolved entry = { pc_offset() - sizeof(Instr), flags, name }; 708 Unresolved entry = { pc_offset() - sizeof(Instr), flags, name };
719 unresolved_.Add(entry); 709 unresolved_.Add(entry);
720 } 710 }
721 } 711 }
722 712
723 713
724 void MacroAssembler::Assert(Condition cc, const char* msg) { 714 void MacroAssembler::Assert(Condition cc, const char* msg) {
725 if (FLAG_debug_code) 715 if (FLAG_debug_code)
726 Check(cc, msg); 716 Check(cc, msg);
727 } 717 }
(...skipping 25 matching lines...) Expand all
753 #endif 743 #endif
754 mov(r0, Operand(p0)); 744 mov(r0, Operand(p0));
755 push(r0); 745 push(r0);
756 mov(r0, Operand(Smi::FromInt(p1 - p0))); 746 mov(r0, Operand(Smi::FromInt(p1 - p0)));
757 push(r0); 747 push(r0);
758 CallRuntime(Runtime::kAbort, 2); 748 CallRuntime(Runtime::kAbort, 2);
759 // will not return here 749 // will not return here
760 } 750 }
761 751
762 } } // namespace v8::internal 752 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/macro-assembler-arm.h ('k') | src/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698