Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 385 | 385 |
| 386 // Setup argc and argv in callee-saved registers. | 386 // Setup argc and argv in callee-saved registers. |
| 387 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; | 387 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; |
| 388 mov(edi, Operand(eax)); | 388 mov(edi, Operand(eax)); |
| 389 lea(esi, Operand(ebp, eax, times_4, offset)); | 389 lea(esi, Operand(ebp, eax, times_4, offset)); |
| 390 | 390 |
| 391 EnterExitFrameEpilogue(2); | 391 EnterExitFrameEpilogue(2); |
| 392 } | 392 } |
| 393 | 393 |
| 394 | 394 |
| 395 void MacroAssembler::EnterApiExitFrame(int stack_space, | 395 void MacroAssembler::EnterApiExitFrame(int argc) { |
| 396 int argc) { | |
| 397 EnterExitFramePrologue(); | 396 EnterExitFramePrologue(); |
| 398 | |
| 399 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; | |
| 400 lea(esi, Operand(ebp, (stack_space * kPointerSize) + offset)); | |
| 401 | |
| 402 EnterExitFrameEpilogue(argc); | 397 EnterExitFrameEpilogue(argc); |
| 403 } | 398 } |
| 404 | 399 |
| 405 | 400 |
| 406 void MacroAssembler::LeaveExitFrame() { | 401 void MacroAssembler::LeaveExitFrame() { |
| 407 // Get the return address from the stack and restore the frame pointer. | 402 // Get the return address from the stack and restore the frame pointer. |
| 408 mov(ecx, Operand(ebp, 1 * kPointerSize)); | 403 mov(ecx, Operand(ebp, 1 * kPointerSize)); |
| 409 mov(ebp, Operand(ebp, 0 * kPointerSize)); | 404 mov(ebp, Operand(ebp, 0 * kPointerSize)); |
| 410 | 405 |
| 411 // Pop the arguments and the receiver from the caller stack. | 406 // Pop the arguments and the receiver from the caller stack. |
| 412 lea(esp, Operand(esi, 1 * kPointerSize)); | 407 lea(esp, Operand(esi, 1 * kPointerSize)); |
| 413 | 408 |
| 414 // Restore current context from top and clear it in debug mode. | 409 // Restore current context from top and clear it in debug mode. |
| 415 ExternalReference context_address(Top::k_context_address); | 410 ExternalReference context_address(Top::k_context_address); |
| 416 mov(esi, Operand::StaticVariable(context_address)); | 411 mov(esi, Operand::StaticVariable(context_address)); |
| 417 #ifdef DEBUG | 412 #ifdef DEBUG |
| 418 mov(Operand::StaticVariable(context_address), Immediate(0)); | 413 mov(Operand::StaticVariable(context_address), Immediate(0)); |
| 419 #endif | 414 #endif |
| 420 | 415 |
| 421 // Push the return address to get ready to return. | 416 // Push the return address to get ready to return. |
| 422 push(ecx); | 417 push(ecx); |
| 423 | 418 |
| 424 // Clear the top frame. | 419 // Clear the top frame. |
| 425 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address); | 420 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address); |
| 426 mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); | 421 mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); |
| 427 } | 422 } |
| 428 | 423 |
| 429 | 424 |
| 425 void MacroAssembler::LeaveApiExitFrame() { | |
| 426 mov(esp, Operand(ebp)); | |
| 427 pop(ebp); | |
| 428 | |
| 429 // Restore current context from top and clear it in debug mode. | |
|
antonm
2010/11/16 14:32:26
I'd suggest (but not insisting) to factor out comm
SeRya
2010/11/16 14:53:28
Done.
| |
| 430 ExternalReference context_address(Top::k_context_address); | |
| 431 mov(esi, Operand::StaticVariable(context_address)); | |
| 432 #ifdef DEBUG | |
| 433 mov(Operand::StaticVariable(context_address), Immediate(0)); | |
| 434 #endif | |
| 435 | |
| 436 // Clear the top frame. | |
| 437 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address); | |
| 438 mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); | |
| 439 } | |
| 440 | |
| 441 | |
| 430 void MacroAssembler::PushTryHandler(CodeLocation try_location, | 442 void MacroAssembler::PushTryHandler(CodeLocation try_location, |
| 431 HandlerType type) { | 443 HandlerType type) { |
| 432 // Adjust this code if not the case. | 444 // Adjust this code if not the case. |
| 433 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); | 445 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); |
| 434 // The pc (return address) is already on TOS. | 446 // The pc (return address) is already on TOS. |
| 435 if (try_location == IN_JAVASCRIPT) { | 447 if (try_location == IN_JAVASCRIPT) { |
| 436 if (type == TRY_CATCH_HANDLER) { | 448 if (type == TRY_CATCH_HANDLER) { |
| 437 push(Immediate(StackHandler::TRY_CATCH)); | 449 push(Immediate(StackHandler::TRY_CATCH)); |
| 438 } else { | 450 } else { |
| 439 push(Immediate(StackHandler::TRY_FINALLY)); | 451 push(Immediate(StackHandler::TRY_FINALLY)); |
| (...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1144 #else | 1156 #else |
| 1145 static const bool kPassHandlesDirectly = false; | 1157 static const bool kPassHandlesDirectly = false; |
| 1146 #endif | 1158 #endif |
| 1147 | 1159 |
| 1148 | 1160 |
| 1149 Operand ApiParameterOperand(int index) { | 1161 Operand ApiParameterOperand(int index) { |
| 1150 return Operand(esp, (index + (kPassHandlesDirectly ? 0 : 1)) * kPointerSize); | 1162 return Operand(esp, (index + (kPassHandlesDirectly ? 0 : 1)) * kPointerSize); |
| 1151 } | 1163 } |
| 1152 | 1164 |
| 1153 | 1165 |
| 1154 void MacroAssembler::PrepareCallApiFunction(int stack_space, int argc) { | 1166 void MacroAssembler::PrepareCallApiFunction(int argc, Register scratch) { |
| 1155 if (kPassHandlesDirectly) { | 1167 if (kPassHandlesDirectly) { |
| 1156 EnterApiExitFrame(stack_space, argc); | 1168 EnterApiExitFrame(argc); |
| 1157 // When handles as passed directly we don't have to allocate extra | 1169 // When handles as passed directly we don't have to allocate extra |
| 1158 // space for and pass an out parameter. | 1170 // space for and pass an out parameter. |
| 1159 } else { | 1171 } else { |
| 1160 // We allocate two additional slots: return value and pointer to it. | 1172 // We allocate two additional slots: return value and pointer to it. |
| 1161 EnterApiExitFrame(stack_space, argc + 2); | 1173 EnterApiExitFrame(argc + 2); |
| 1162 } | |
| 1163 } | |
| 1164 | 1174 |
| 1165 | |
| 1166 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(ApiFunction* function, | |
| 1167 int argc) { | |
| 1168 if (!kPassHandlesDirectly) { | |
| 1169 // The argument slots are filled as follows: | 1175 // The argument slots are filled as follows: |
| 1170 // | 1176 // |
| 1171 // n + 1: output cell | 1177 // n + 1: output cell |
| 1172 // n: arg n | 1178 // n: arg n |
| 1173 // ... | 1179 // ... |
| 1174 // 1: arg1 | 1180 // 1: arg1 |
| 1175 // 0: pointer to the output cell | 1181 // 0: pointer to the output cell |
| 1176 // | 1182 // |
| 1177 // Note that this is one more "argument" than the function expects | 1183 // Note that this is one more "argument" than the function expects |
| 1178 // so the out cell will have to be popped explicitly after returning | 1184 // so the out cell will have to be popped explicitly after returning |
| 1179 // from the function. The out cell contains Handle. | 1185 // from the function. The out cell contains Handle. |
| 1180 lea(eax, Operand(esp, (argc + 1) * kPointerSize)); // pointer to out cell. | 1186 |
| 1181 mov(Operand(esp, 0 * kPointerSize), eax); // output. | 1187 // pointer to out cell. |
| 1182 mov(Operand(esp, (argc + 1) * kPointerSize), Immediate(0)); // out cell. | 1188 lea(scratch, Operand(esp, (argc + 1) * kPointerSize)); |
| 1189 mov(Operand(esp, 0 * kPointerSize), scratch); // output. | |
| 1190 if (FLAG_debug_code) { | |
| 1191 mov(Operand(esp, (argc + 1) * kPointerSize), Immediate(0)); // out cell. | |
| 1192 } | |
| 1183 } | 1193 } |
| 1194 } | |
| 1184 | 1195 |
| 1196 | |
| 1197 MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(ApiFunction* function, | |
| 1198 int stack_space) { | |
| 1185 ExternalReference next_address = | 1199 ExternalReference next_address = |
| 1186 ExternalReference::handle_scope_next_address(); | 1200 ExternalReference::handle_scope_next_address(); |
| 1187 ExternalReference limit_address = | 1201 ExternalReference limit_address = |
| 1188 ExternalReference::handle_scope_limit_address(); | 1202 ExternalReference::handle_scope_limit_address(); |
| 1189 ExternalReference level_address = | 1203 ExternalReference level_address = |
| 1190 ExternalReference::handle_scope_level_address(); | 1204 ExternalReference::handle_scope_level_address(); |
| 1191 | 1205 |
| 1192 // Allocate HandleScope in callee-save registers. | 1206 // Allocate HandleScope in callee-save registers. |
| 1193 mov(ebx, Operand::StaticVariable(next_address)); | 1207 mov(ebx, Operand::StaticVariable(next_address)); |
| 1194 mov(edi, Operand::StaticVariable(limit_address)); | 1208 mov(edi, Operand::StaticVariable(limit_address)); |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1223 cmp(edi, Operand::StaticVariable(limit_address)); | 1237 cmp(edi, Operand::StaticVariable(limit_address)); |
| 1224 j(not_equal, &delete_allocated_handles, not_taken); | 1238 j(not_equal, &delete_allocated_handles, not_taken); |
| 1225 bind(&leave_exit_frame); | 1239 bind(&leave_exit_frame); |
| 1226 | 1240 |
| 1227 // Check if the function scheduled an exception. | 1241 // Check if the function scheduled an exception. |
| 1228 ExternalReference scheduled_exception_address = | 1242 ExternalReference scheduled_exception_address = |
| 1229 ExternalReference::scheduled_exception_address(); | 1243 ExternalReference::scheduled_exception_address(); |
| 1230 cmp(Operand::StaticVariable(scheduled_exception_address), | 1244 cmp(Operand::StaticVariable(scheduled_exception_address), |
| 1231 Immediate(Factory::the_hole_value())); | 1245 Immediate(Factory::the_hole_value())); |
| 1232 j(not_equal, &promote_scheduled_exception, not_taken); | 1246 j(not_equal, &promote_scheduled_exception, not_taken); |
| 1233 LeaveExitFrame(); | 1247 LeaveApiExitFrame(); |
| 1234 ret(0); | 1248 ret(stack_space * kPointerSize); |
| 1235 bind(&promote_scheduled_exception); | 1249 bind(&promote_scheduled_exception); |
| 1236 MaybeObject* result = | 1250 MaybeObject* result = |
| 1237 TryTailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); | 1251 TryTailCallRuntime(Runtime::kPromoteScheduledException, 0, 1); |
| 1238 if (result->IsFailure()) { | 1252 if (result->IsFailure()) { |
| 1239 return result; | 1253 return result; |
| 1240 } | 1254 } |
| 1241 bind(&empty_handle); | 1255 bind(&empty_handle); |
| 1242 // It was zero; the result is undefined. | 1256 // It was zero; the result is undefined. |
| 1243 mov(eax, Factory::undefined_value()); | 1257 mov(eax, Factory::undefined_value()); |
| 1244 jmp(&prologue); | 1258 jmp(&prologue); |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1799 | 1813 |
| 1800 // Check that the code was patched as expected. | 1814 // Check that the code was patched as expected. |
| 1801 ASSERT(masm_.pc_ == address_ + size_); | 1815 ASSERT(masm_.pc_ == address_ + size_); |
| 1802 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 1816 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
| 1803 } | 1817 } |
| 1804 | 1818 |
| 1805 | 1819 |
| 1806 } } // namespace v8::internal | 1820 } } // namespace v8::internal |
| 1807 | 1821 |
| 1808 #endif // V8_TARGET_ARCH_IA32 | 1822 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |