OLD | NEW |
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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 | 77 |
78 void MacroAssembler::Jump(Register target, Condition cond) { | 78 void MacroAssembler::Jump(Register target, Condition cond) { |
79 #if USE_BX | 79 #if USE_BX |
80 bx(target, cond); | 80 bx(target, cond); |
81 #else | 81 #else |
82 mov(pc, Operand(target), LeaveCC, cond); | 82 mov(pc, Operand(target), LeaveCC, cond); |
83 #endif | 83 #endif |
84 } | 84 } |
85 | 85 |
86 | 86 |
87 void MacroAssembler::Jump(intptr_t target, RelocMode rmode, Condition cond) { | 87 void MacroAssembler::Jump(intptr_t target, RelocInfo::Mode rmode, |
| 88 Condition cond) { |
88 #if USE_BX | 89 #if USE_BX |
89 mov(ip, Operand(target, rmode), LeaveCC, cond); | 90 mov(ip, Operand(target, rmode), LeaveCC, cond); |
90 bx(ip, cond); | 91 bx(ip, cond); |
91 #else | 92 #else |
92 mov(pc, Operand(target, rmode), LeaveCC, cond); | 93 mov(pc, Operand(target, rmode), LeaveCC, cond); |
93 #endif | 94 #endif |
94 } | 95 } |
95 | 96 |
96 | 97 |
97 void MacroAssembler::Jump(byte* target, RelocMode rmode, Condition cond) { | 98 void MacroAssembler::Jump(byte* target, RelocInfo::Mode rmode, |
98 ASSERT(!is_code_target(rmode)); | 99 Condition cond) { |
| 100 ASSERT(!RelocInfo::IsCodeTarget(rmode)); |
99 Jump(reinterpret_cast<intptr_t>(target), rmode, cond); | 101 Jump(reinterpret_cast<intptr_t>(target), rmode, cond); |
100 } | 102 } |
101 | 103 |
102 | 104 |
103 void MacroAssembler::Jump(Handle<Code> code, RelocMode rmode, Condition cond) { | 105 void MacroAssembler::Jump(Handle<Code> code, RelocInfo::Mode rmode, |
104 ASSERT(is_code_target(rmode)); | 106 Condition cond) { |
| 107 ASSERT(RelocInfo::IsCodeTarget(rmode)); |
105 // 'code' is always generated ARM code, never THUMB code | 108 // 'code' is always generated ARM code, never THUMB code |
106 Jump(reinterpret_cast<intptr_t>(code.location()), rmode, cond); | 109 Jump(reinterpret_cast<intptr_t>(code.location()), rmode, cond); |
107 } | 110 } |
108 | 111 |
109 | 112 |
110 void MacroAssembler::Call(Register target, Condition cond) { | 113 void MacroAssembler::Call(Register target, Condition cond) { |
111 #if USE_BLX | 114 #if USE_BLX |
112 blx(target, cond); | 115 blx(target, cond); |
113 #else | 116 #else |
114 // set lr for return at current pc + 8 | 117 // set lr for return at current pc + 8 |
115 mov(lr, Operand(pc), LeaveCC, cond); | 118 mov(lr, Operand(pc), LeaveCC, cond); |
116 mov(pc, Operand(target), LeaveCC, cond); | 119 mov(pc, Operand(target), LeaveCC, cond); |
117 #endif | 120 #endif |
118 } | 121 } |
119 | 122 |
120 | 123 |
121 void MacroAssembler::Call(intptr_t target, RelocMode rmode, Condition cond) { | 124 void MacroAssembler::Call(intptr_t target, RelocInfo::Mode rmode, |
| 125 Condition cond) { |
122 #if !defined(__arm__) | 126 #if !defined(__arm__) |
123 if (rmode == runtime_entry) { | 127 if (rmode == RelocInfo::RUNTIME_ENTRY) { |
124 mov(r2, Operand(target, rmode), LeaveCC, cond); | 128 mov(r2, Operand(target, rmode), LeaveCC, cond); |
125 // Set lr for return at current pc + 8. | 129 // Set lr for return at current pc + 8. |
126 mov(lr, Operand(pc), LeaveCC, cond); | 130 mov(lr, Operand(pc), LeaveCC, cond); |
127 // Emit a ldr<cond> pc, [pc + offset of target in constant pool]. | 131 // Emit a ldr<cond> pc, [pc + offset of target in constant pool]. |
128 // Notify the simulator of the transition to C code. | 132 // Notify the simulator of the transition to C code. |
129 swi(assembler::arm::call_rt_r2); | 133 swi(assembler::arm::call_rt_r2); |
130 } else { | 134 } else { |
131 // set lr for return at current pc + 8 | 135 // set lr for return at current pc + 8 |
132 mov(lr, Operand(pc), LeaveCC, cond); | 136 mov(lr, Operand(pc), LeaveCC, cond); |
133 // emit a ldr<cond> pc, [pc + offset of target in constant pool] | 137 // emit a ldr<cond> pc, [pc + offset of target in constant pool] |
134 mov(pc, Operand(target, rmode), LeaveCC, cond); | 138 mov(pc, Operand(target, rmode), LeaveCC, cond); |
135 } | 139 } |
136 #else | 140 #else |
137 // Set lr for return at current pc + 8. | 141 // Set lr for return at current pc + 8. |
138 mov(lr, Operand(pc), LeaveCC, cond); | 142 mov(lr, Operand(pc), LeaveCC, cond); |
139 // Emit a ldr<cond> pc, [pc + offset of target in constant pool]. | 143 // Emit a ldr<cond> pc, [pc + offset of target in constant pool]. |
140 mov(pc, Operand(target, rmode), LeaveCC, cond); | 144 mov(pc, Operand(target, rmode), LeaveCC, cond); |
141 #endif // !defined(__arm__) | 145 #endif // !defined(__arm__) |
142 // If USE_BLX is defined, we could emit a 'mov ip, target', followed by a | 146 // If USE_BLX is defined, we could emit a 'mov ip, target', followed by a |
143 // 'blx ip'; however, the code would not be shorter than the above sequence | 147 // 'blx ip'; however, the code would not be shorter than the above sequence |
144 // and the target address of the call would be referenced by the first | 148 // and the target address of the call would be referenced by the first |
145 // instruction rather than the second one, which would make it harder to patch | 149 // instruction rather than the second one, which would make it harder to patch |
146 // (two instructions before the return address, instead of one). | 150 // (two instructions before the return address, instead of one). |
147 ASSERT(kTargetAddrToReturnAddrDist == sizeof(Instr)); | 151 ASSERT(kTargetAddrToReturnAddrDist == sizeof(Instr)); |
148 } | 152 } |
149 | 153 |
150 | 154 |
151 void MacroAssembler::Call(byte* target, RelocMode rmode, Condition cond) { | 155 void MacroAssembler::Call(byte* target, RelocInfo::Mode rmode, |
152 ASSERT(!is_code_target(rmode)); | 156 Condition cond) { |
| 157 ASSERT(!RelocInfo::IsCodeTarget(rmode)); |
153 Call(reinterpret_cast<intptr_t>(target), rmode, cond); | 158 Call(reinterpret_cast<intptr_t>(target), rmode, cond); |
154 } | 159 } |
155 | 160 |
156 | 161 |
157 void MacroAssembler::Call(Handle<Code> code, RelocMode rmode, Condition cond) { | 162 void MacroAssembler::Call(Handle<Code> code, RelocInfo::Mode rmode, |
158 ASSERT(is_code_target(rmode)); | 163 Condition cond) { |
| 164 ASSERT(RelocInfo::IsCodeTarget(rmode)); |
159 // 'code' is always generated ARM code, never THUMB code | 165 // 'code' is always generated ARM code, never THUMB code |
160 Call(reinterpret_cast<intptr_t>(code.location()), rmode, cond); | 166 Call(reinterpret_cast<intptr_t>(code.location()), rmode, cond); |
161 } | 167 } |
162 | 168 |
163 | 169 |
164 void MacroAssembler::Ret() { | 170 void MacroAssembler::Ret() { |
165 #if USE_BX | 171 #if USE_BX |
166 bx(lr); | 172 bx(lr); |
167 #else | 173 #else |
168 mov(pc, Operand(lr)); | 174 mov(pc, Operand(lr)); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 | 329 |
324 if (!definitely_matches) { | 330 if (!definitely_matches) { |
325 if (!code_constant.is_null()) { | 331 if (!code_constant.is_null()) { |
326 mov(r3, Operand(code_constant)); | 332 mov(r3, Operand(code_constant)); |
327 add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag)); | 333 add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag)); |
328 } | 334 } |
329 | 335 |
330 Handle<Code> adaptor = | 336 Handle<Code> adaptor = |
331 Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); | 337 Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)); |
332 if (flag == CALL_FUNCTION) { | 338 if (flag == CALL_FUNCTION) { |
333 Call(adaptor, code_target); | 339 Call(adaptor, RelocInfo::CODE_TARGET); |
334 b(done); | 340 b(done); |
335 } else { | 341 } else { |
336 Jump(adaptor, code_target); | 342 Jump(adaptor, RelocInfo::CODE_TARGET); |
337 } | 343 } |
338 bind(®ular_invoke); | 344 bind(®ular_invoke); |
339 } | 345 } |
340 } | 346 } |
341 | 347 |
342 | 348 |
343 void MacroAssembler::InvokeCode(Register code, | 349 void MacroAssembler::InvokeCode(Register code, |
344 const ParameterCount& expected, | 350 const ParameterCount& expected, |
345 const ParameterCount& actual, | 351 const ParameterCount& actual, |
346 InvokeFlag flag) { | 352 InvokeFlag flag) { |
347 Label done; | 353 Label done; |
348 | 354 |
349 InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag); | 355 InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag); |
350 if (flag == CALL_FUNCTION) { | 356 if (flag == CALL_FUNCTION) { |
351 Call(code); | 357 Call(code); |
352 } else { | 358 } else { |
353 ASSERT(flag == JUMP_FUNCTION); | 359 ASSERT(flag == JUMP_FUNCTION); |
354 Jump(code); | 360 Jump(code); |
355 } | 361 } |
356 | 362 |
357 // Continue here if InvokePrologue does handle the invocation due to | 363 // Continue here if InvokePrologue does handle the invocation due to |
358 // mismatched parameter counts. | 364 // mismatched parameter counts. |
359 bind(&done); | 365 bind(&done); |
360 } | 366 } |
361 | 367 |
362 | 368 |
363 void MacroAssembler::InvokeCode(Handle<Code> code, | 369 void MacroAssembler::InvokeCode(Handle<Code> code, |
364 const ParameterCount& expected, | 370 const ParameterCount& expected, |
365 const ParameterCount& actual, | 371 const ParameterCount& actual, |
366 RelocMode rmode, | 372 RelocInfo::Mode rmode, |
367 InvokeFlag flag) { | 373 InvokeFlag flag) { |
368 Label done; | 374 Label done; |
369 | 375 |
370 InvokePrologue(expected, actual, code, no_reg, &done, flag); | 376 InvokePrologue(expected, actual, code, no_reg, &done, flag); |
371 if (flag == CALL_FUNCTION) { | 377 if (flag == CALL_FUNCTION) { |
372 Call(code, rmode); | 378 Call(code, rmode); |
373 } else { | 379 } else { |
374 Jump(code, rmode); | 380 Jump(code, rmode); |
375 } | 381 } |
376 | 382 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 // object. | 602 // object. |
597 ldr(scratch, FieldMemOperand(scratch, JSGlobalObject::kSecurityTokenOffset)); | 603 ldr(scratch, FieldMemOperand(scratch, JSGlobalObject::kSecurityTokenOffset)); |
598 ldr(ip, FieldMemOperand(holder_reg, JSGlobalObject::kSecurityTokenOffset)); | 604 ldr(ip, FieldMemOperand(holder_reg, JSGlobalObject::kSecurityTokenOffset)); |
599 cmp(scratch, Operand(ip)); | 605 cmp(scratch, Operand(ip)); |
600 b(ne, miss); | 606 b(ne, miss); |
601 } | 607 } |
602 | 608 |
603 | 609 |
604 void MacroAssembler::CallStub(CodeStub* stub) { | 610 void MacroAssembler::CallStub(CodeStub* stub) { |
605 ASSERT(allow_stub_calls()); // stub calls are not allowed in some stubs | 611 ASSERT(allow_stub_calls()); // stub calls are not allowed in some stubs |
606 Call(stub->GetCode(), code_target); | 612 Call(stub->GetCode(), RelocInfo::CODE_TARGET); |
607 } | |
608 | |
609 | |
610 void MacroAssembler::CallJSExitStub(CodeStub* stub) { | |
611 ASSERT(allow_stub_calls()); // stub calls are not allowed in some stubs | |
612 Call(stub->GetCode(), exit_js_frame); | |
613 } | 613 } |
614 | 614 |
615 | 615 |
616 void MacroAssembler::StubReturn(int argc) { | 616 void MacroAssembler::StubReturn(int argc) { |
617 ASSERT(argc >= 1 && generating_stub()); | 617 ASSERT(argc >= 1 && generating_stub()); |
618 if (argc > 1) | 618 if (argc > 1) |
619 add(sp, sp, Operand((argc - 1) * kPointerSize)); | 619 add(sp, sp, Operand((argc - 1) * kPointerSize)); |
620 Ret(); | 620 Ret(); |
621 } | 621 } |
622 | 622 |
(...skipping 28 matching lines...) Expand all Loading... |
651 } | 651 } |
652 | 652 |
653 | 653 |
654 void MacroAssembler::JumpToBuiltin(const ExternalReference& builtin) { | 654 void MacroAssembler::JumpToBuiltin(const ExternalReference& builtin) { |
655 #if defined(__thumb__) | 655 #if defined(__thumb__) |
656 // Thumb mode builtin. | 656 // Thumb mode builtin. |
657 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1); | 657 ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1); |
658 #endif | 658 #endif |
659 mov(r1, Operand(builtin)); | 659 mov(r1, Operand(builtin)); |
660 CEntryStub stub; | 660 CEntryStub stub; |
661 Jump(stub.GetCode(), code_target); | 661 Jump(stub.GetCode(), RelocInfo::CODE_TARGET); |
662 } | 662 } |
663 | 663 |
664 | 664 |
665 Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id, | 665 Handle<Code> MacroAssembler::ResolveBuiltin(Builtins::JavaScript id, |
666 bool* resolved) { | 666 bool* resolved) { |
667 // Contract with compiled functions is that the function is passed in r1. | 667 // Contract with compiled functions is that the function is passed in r1. |
668 int builtins_offset = | 668 int builtins_offset = |
669 JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize); | 669 JSBuiltinsObject::kJSBuiltinsOffset + (id * kPointerSize); |
670 ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); | 670 ldr(r1, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_INDEX))); |
671 ldr(r1, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset)); | 671 ldr(r1, FieldMemOperand(r1, GlobalObject::kBuiltinsOffset)); |
672 ldr(r1, FieldMemOperand(r1, builtins_offset)); | 672 ldr(r1, FieldMemOperand(r1, builtins_offset)); |
673 | 673 |
674 return Builtins::GetCode(id, resolved); | 674 return Builtins::GetCode(id, resolved); |
675 } | 675 } |
676 | 676 |
677 | 677 |
678 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, | 678 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, |
679 InvokeJSFlags flags) { | 679 InvokeJSFlags flags) { |
680 bool resolved; | 680 bool resolved; |
681 Handle<Code> code = ResolveBuiltin(id, &resolved); | 681 Handle<Code> code = ResolveBuiltin(id, &resolved); |
682 | 682 |
683 if (flags == CALL_JS) { | 683 if (flags == CALL_JS) { |
684 Call(code, code_target); | 684 Call(code, RelocInfo::CODE_TARGET); |
685 } else { | 685 } else { |
686 ASSERT(flags == JUMP_JS); | 686 ASSERT(flags == JUMP_JS); |
687 Jump(code, code_target); | 687 Jump(code, RelocInfo::CODE_TARGET); |
688 } | 688 } |
689 | 689 |
690 if (!resolved) { | 690 if (!resolved) { |
691 const char* name = Builtins::GetName(id); | 691 const char* name = Builtins::GetName(id); |
692 int argc = Builtins::GetArgumentsCount(id); | 692 int argc = Builtins::GetArgumentsCount(id); |
693 uint32_t flags = | 693 uint32_t flags = |
694 Bootstrapper::FixupFlagsArgumentsCount::encode(argc) | | 694 Bootstrapper::FixupFlagsArgumentsCount::encode(argc) | |
695 Bootstrapper::FixupFlagsIsPCRelative::encode(true); | 695 Bootstrapper::FixupFlagsIsPCRelative::encode(true); |
696 Unresolved entry = { pc_offset() - sizeof(Instr), flags, name }; | 696 Unresolved entry = { pc_offset() - sizeof(Instr), flags, name }; |
697 unresolved_.Add(entry); | 697 unresolved_.Add(entry); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
748 #endif | 748 #endif |
749 mov(r0, Operand(p0)); | 749 mov(r0, Operand(p0)); |
750 push(r0); | 750 push(r0); |
751 mov(r0, Operand(Smi::FromInt(p1 - p0))); | 751 mov(r0, Operand(Smi::FromInt(p1 - p0))); |
752 push(r0); | 752 push(r0); |
753 CallRuntime(Runtime::kAbort, 2); | 753 CallRuntime(Runtime::kAbort, 2); |
754 // will not return here | 754 // will not return here |
755 } | 755 } |
756 | 756 |
757 } } // namespace v8::internal | 757 } } // namespace v8::internal |
OLD | NEW |