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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/macro-assembler-arm.h ('k') | src/macro-assembler-ia32.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/macro-assembler-arm.cc
===================================================================
--- src/macro-assembler-arm.cc (revision 288)
+++ src/macro-assembler-arm.cc (working copy)
@@ -249,94 +249,28 @@
}
-void MacroAssembler::EnterJSFrame(int argc) {
- // Generate code entering a JS function called from a JS function
- // stack: receiver, arguments
- // r0: number of arguments (not including function, nor receiver)
- // r1: preserved
- // sp: stack pointer
- // fp: frame pointer
- // cp: callee's context
- // pp: caller's parameter pointer
- // lr: return address
+void MacroAssembler::EnterInternalFrame() {
+ // r0-r3: preserved
+ int type = StackFrame::INTERNAL;
- // compute parameter pointer before making changes
- // ip = sp + kPointerSize*(args_len+1); // +1 for receiver
- add(ip, sp, Operand(r0, LSL, kPointerSizeLog2));
- add(ip, ip, Operand(kPointerSize));
+ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
+ mov(ip, Operand(Smi::FromInt(type)));
+ push(ip);
+ mov(ip, Operand(0));
+ push(ip); // Push an empty code cache slot.
+ add(fp, sp, Operand(3 * kPointerSize)); // Adjust FP to point to saved FP.
+}
- // push extra parameters if we don't have enough
- // (this can only happen if argc > 0 to begin with)
- if (argc > 0) {
- Label loop, done;
- // assume enough arguments to be the most common case
- sub(r2, r0, Operand(argc), SetCC); // number of missing arguments
- b(ge, &done); // enough arguments
-
- // not enough arguments
- mov(r3, Operand(Factory::undefined_value()));
- bind(&loop);
- push(r3);
- add(r2, r2, Operand(1), SetCC);
- b(lt, &loop);
-
- bind(&done);
- }
-
- mov(r3, Operand(r0)); // args_len to be saved
- mov(r2, Operand(cp)); // context to be saved
-
- // push in reverse order: context (r2), args_len (r3), caller_pp, caller_fp,
- // sp_on_exit (ip == pp, may be patched on exit), return address
- stm(db_w, sp, r2.bit() | r3.bit() | pp.bit() | fp.bit() |
- ip.bit() | lr.bit());
-
- // Setup new frame pointer.
- add(fp, sp, Operand(-StandardFrameConstants::kContextOffset));
- mov(pp, Operand(ip)); // setup new parameter pointer
- mov(r0, Operand(0)); // spare slot to store caller code object during GC
- push(r0);
+void MacroAssembler::ExitInternalFrame() {
+ // r0: preserved
// r1: preserved
-}
+ // r2: preserved
-
-void MacroAssembler::ExitJSFrame(ExitJSFlag flag) {
- // r0: result
- // sp: stack pointer
- // fp: frame pointer
- // pp: parameter pointer
-
- if (flag == DO_NOT_RETURN) {
- add(r3, fp, Operand(JavaScriptFrameConstants::kSavedRegistersOffset));
- }
-
- if (flag == DO_NOT_RETURN) {
- // restore sp as caller_sp (not as pp)
- str(r3, MemOperand(fp, JavaScriptFrameConstants::kSPOnExitOffset));
- }
-
- if (flag == DO_NOT_RETURN && generating_stub()) {
- // If we're generating a stub, we need to preserve the link
- // register to be able to return to the place the stub was called
- // from.
- mov(ip, Operand(lr));
- }
-
- mov(sp, Operand(fp)); // respect ABI stack constraint
- ldm(ia, sp, pp.bit() | fp.bit() | sp.bit() |
- ((flag == RETURN) ? pc.bit() : lr.bit()));
-
- if (flag == DO_NOT_RETURN && generating_stub()) {
- // Return to the place where the stub was called without
- // clobbering the value of the link register.
- mov(pc, Operand(ip));
- }
-
- // r0: result
- // sp: points to function arg (if return) or to last arg (if no return)
- // fp: restored frame pointer
- // pp: restored parameter pointer
+ // Drop the execution stack down to the frame pointer and restore the caller
+ // frame pointer and return address.
+ mov(sp, fp);
+ ldm(ia_w, sp, fp.bit() | lr.bit());
}
@@ -346,13 +280,58 @@
Register code_reg,
Label* done,
InvokeFlag flag) {
- if (actual.is_immediate()) {
- mov(r0, Operand(actual.immediate())); // Push the number of arguments.
+ bool definitely_matches = false;
+ Label regular_invoke;
+
+ // Check whether the expected and actual arguments count match. If not,
+ // setup registers according to contract with ArgumentsAdaptorTrampoline:
+ // r0: actual arguments count
+ // r1: function (passed through to callee)
+ // r2: expected arguments count
+ // r3: callee code entry
+
+ // The code below is made a lot easier because the calling code already sets
+ // up actual and expected registers according to the contract if values are
+ // passed in registers.
+ ASSERT(actual.is_immediate() || actual.reg().is(r0));
+ ASSERT(expected.is_immediate() || expected.reg().is(r2));
+ ASSERT((!code_constant.is_null() && code_reg.is(no_reg)) || code_reg.is(r3));
+
+ if (expected.is_immediate()) {
+ ASSERT(actual.is_immediate());
+ if (expected.immediate() == actual.immediate()) {
+ definitely_matches = true;
+ } else {
+ mov(r0, Operand(actual.immediate()));
+ mov(r2, Operand(expected.immediate()));
+ }
} else {
- if (!actual.reg().is(r0)) {
- mov(r0, Operand(actual.reg()));
+ if (actual.is_immediate()) {
+ cmp(expected.reg(), Operand(actual.immediate()));
+ b(eq, &regular_invoke);
+ mov(r0, Operand(actual.immediate()));
+ } else {
+ cmp(expected.reg(), Operand(actual.reg()));
+ b(eq, &regular_invoke);
}
}
+
+ if (!definitely_matches) {
+ if (!code_constant.is_null()) {
+ mov(r3, Operand(code_constant));
+ add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
+ }
+
+ Handle<Code> adaptor =
+ Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline));
+ if (flag == CALL_FUNCTION) {
+ Call(adaptor, code_target);
+ b(done);
+ } else {
+ Jump(adaptor, code_target);
+ }
+ bind(&regular_invoke);
+ }
}
@@ -402,19 +381,9 @@
// Contract with called JS functions requires that function is passed in r1.
ASSERT(fun.is(r1));
- Register code_reg = r3;
Register expected_reg = r2;
+ Register code_reg = r3;
- // Make sure that the code and expected registers do not collide with the
- // actual register being passed in.
- if (actual.is_reg()) {
- if (actual.reg().is(code_reg)) {
- code_reg = r4;
- } else if (actual.reg().is(expected_reg)) {
- expected_reg = r4;
- }
- }
-
ldr(code_reg, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
ldr(expected_reg,
@@ -507,7 +476,7 @@
mov(r0, Operand(Smi::FromInt(StackHandler::kCodeNotPresent))); // new TOS
push(r0);
} else {
- // Must preserve r0-r3, r5-r7 are available.
+ // Must preserve r0-r4, r5-r7 are available.
ASSERT(try_location == IN_JS_ENTRY);
// The parameter pointer is meaningless here and fp does not point to a JS
// frame. So we save NULL for both pp and fp. We expect the code throwing an
@@ -688,39 +657,60 @@
}
-void MacroAssembler::InvokeBuiltin(const char* name,
- int argc,
- InvokeJSFlags flags) {
- Handle<String> symbol = Factory::LookupAsciiSymbol(name);
- Object* object = Top::security_context_builtins()->GetProperty(*symbol);
- bool unresolved = true;
- Code* code = Builtins::builtin(Builtins::Illegal);
+Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id,
+ bool* resolved) {
+ // Contract with compiled functions is that the function is passed in r1.
+ int builtins_offset =
+ JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize);
+ ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX)));
+ ldr(r1, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset));
+ ldr(r1, FieldMemOperand(r1, builtins_offset));
- if (object->IsJSFunction()) {
- Handle<JSFunction> function(JSFunction::cast(object));
- if (function->is_compiled() || CompileLazy(function, CLEAR_EXCEPTION)) {
- code = function->code();
- unresolved = false;
- }
- }
+ return Builtins::GetCode(id, resolved);
+}
+
+void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
+ InvokeJSFlags flags) {
+ bool resolved;
+ Handle<Code> code = ResolveBuiltin(id, &resolved);
+
if (flags == CALL_JS) {
- Call(Handle<Code>(code), code_target);
+ Call(code, code_target);
} else {
ASSERT(flags == JUMP_JS);
- Jump(Handle<Code>(code), code_target);
+ Jump(code, code_target);
}
- if (unresolved) {
+ if (!resolved) {
+ const char* name = Builtins::GetName(id);
+ int argc = Builtins::GetArgumentsCount(id);
uint32_t flags =
Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
- Bootstrapper::FixupFlagsIsPCRelative::encode(false);
+ Bootstrapper::FixupFlagsIsPCRelative::encode(true);
Unresolved entry = { pc_offset() - sizeof(Instr), flags, name };
unresolved_.Add(entry);
}
}
+void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
+ bool resolved;
+ Handle<Code> code = ResolveBuiltin(id, &resolved);
+
+ mov(target, Operand(code));
+ if (!resolved) {
+ const char* name = Builtins::GetName(id);
+ int argc = Builtins::GetArgumentsCount(id);
+ uint32_t flags =
+ Bootstrapper::FixupFlagsArgumentsCount::encode(argc) |
+ Bootstrapper::FixupFlagsIsPCRelative::encode(true);
+ Unresolved entry = { pc_offset() - sizeof(Instr), flags, name };
+ unresolved_.Add(entry);
+ }
+}
+
+
void MacroAssembler::Assert(Condition cc, const char* msg) {
if (FLAG_debug_code)
Check(cc, msg);
« 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