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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 } else { | 209 } else { |
210 RecordWriteStub stub(object, dst, value); | 210 RecordWriteStub stub(object, dst, value); |
211 CallStub(&stub); | 211 CallStub(&stub); |
212 } | 212 } |
213 } | 213 } |
214 | 214 |
215 bind(&done); | 215 bind(&done); |
216 } | 216 } |
217 | 217 |
218 | 218 |
| 219 #ifdef ENABLE_DEBUGGER_SUPPORT |
219 void MacroAssembler::SaveRegistersToMemory(RegList regs) { | 220 void MacroAssembler::SaveRegistersToMemory(RegList regs) { |
220 ASSERT((regs & ~kJSCallerSaved) == 0); | 221 ASSERT((regs & ~kJSCallerSaved) == 0); |
221 // Copy the content of registers to memory location. | 222 // Copy the content of registers to memory location. |
222 for (int i = 0; i < kNumJSCallerSaved; i++) { | 223 for (int i = 0; i < kNumJSCallerSaved; i++) { |
223 int r = JSCallerSavedCode(i); | 224 int r = JSCallerSavedCode(i); |
224 if ((regs & (1 << r)) != 0) { | 225 if ((regs & (1 << r)) != 0) { |
225 Register reg = { r }; | 226 Register reg = { r }; |
226 ExternalReference reg_addr = | 227 ExternalReference reg_addr = |
227 ExternalReference(Debug_Address::Register(i)); | 228 ExternalReference(Debug_Address::Register(i)); |
228 mov(Operand::StaticVariable(reg_addr), reg); | 229 mov(Operand::StaticVariable(reg_addr), reg); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 int r = JSCallerSavedCode(i); | 284 int r = JSCallerSavedCode(i); |
284 if ((regs & (1 << r)) != 0) { | 285 if ((regs & (1 << r)) != 0) { |
285 mov(scratch, Operand(base, 0)); | 286 mov(scratch, Operand(base, 0)); |
286 ExternalReference reg_addr = | 287 ExternalReference reg_addr = |
287 ExternalReference(Debug_Address::Register(i)); | 288 ExternalReference(Debug_Address::Register(i)); |
288 mov(Operand::StaticVariable(reg_addr), scratch); | 289 mov(Operand::StaticVariable(reg_addr), scratch); |
289 lea(base, Operand(base, kPointerSize)); | 290 lea(base, Operand(base, kPointerSize)); |
290 } | 291 } |
291 } | 292 } |
292 } | 293 } |
293 | 294 #endif |
294 | 295 |
295 void MacroAssembler::Set(Register dst, const Immediate& x) { | 296 void MacroAssembler::Set(Register dst, const Immediate& x) { |
296 if (x.is_zero()) { | 297 if (x.is_zero()) { |
297 xor_(dst, Operand(dst)); // shorter than mov | 298 xor_(dst, Operand(dst)); // shorter than mov |
298 } else { | 299 } else { |
299 mov(dst, x); | 300 mov(dst, x); |
300 } | 301 } |
301 } | 302 } |
302 | 303 |
303 | 304 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address); | 372 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address); |
372 ExternalReference context_address(Top::k_context_address); | 373 ExternalReference context_address(Top::k_context_address); |
373 mov(Operand::StaticVariable(c_entry_fp_address), ebp); | 374 mov(Operand::StaticVariable(c_entry_fp_address), ebp); |
374 mov(Operand::StaticVariable(context_address), esi); | 375 mov(Operand::StaticVariable(context_address), esi); |
375 | 376 |
376 // Setup argc and argv in callee-saved registers. | 377 // Setup argc and argv in callee-saved registers. |
377 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; | 378 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; |
378 mov(edi, Operand(eax)); | 379 mov(edi, Operand(eax)); |
379 lea(esi, Operand(ebp, eax, times_4, offset)); | 380 lea(esi, Operand(ebp, eax, times_4, offset)); |
380 | 381 |
| 382 #ifdef ENABLE_DEBUGGER_SUPPORT |
381 // Save the state of all registers to the stack from the memory | 383 // Save the state of all registers to the stack from the memory |
382 // location. This is needed to allow nested break points. | 384 // location. This is needed to allow nested break points. |
383 if (type == StackFrame::EXIT_DEBUG) { | 385 if (type == StackFrame::EXIT_DEBUG) { |
384 // TODO(1243899): This should be symmetric to | 386 // TODO(1243899): This should be symmetric to |
385 // CopyRegistersFromStackToMemory() but it isn't! esp is assumed | 387 // CopyRegistersFromStackToMemory() but it isn't! esp is assumed |
386 // correct here, but computed for the other call. Very error | 388 // correct here, but computed for the other call. Very error |
387 // prone! FIX THIS. Actually there are deeper problems with | 389 // prone! FIX THIS. Actually there are deeper problems with |
388 // register saving than this asymmetry (see the bug report | 390 // register saving than this asymmetry (see the bug report |
389 // associated with this issue). | 391 // associated with this issue). |
390 PushRegistersFromMemory(kJSCallerSaved); | 392 PushRegistersFromMemory(kJSCallerSaved); |
391 } | 393 } |
| 394 #endif |
392 | 395 |
393 // Reserve space for two arguments: argc and argv. | 396 // Reserve space for two arguments: argc and argv. |
394 sub(Operand(esp), Immediate(2 * kPointerSize)); | 397 sub(Operand(esp), Immediate(2 * kPointerSize)); |
395 | 398 |
396 // Get the required frame alignment for the OS. | 399 // Get the required frame alignment for the OS. |
397 static const int kFrameAlignment = OS::ActivationFrameAlignment(); | 400 static const int kFrameAlignment = OS::ActivationFrameAlignment(); |
398 if (kFrameAlignment > 0) { | 401 if (kFrameAlignment > 0) { |
399 ASSERT(IsPowerOf2(kFrameAlignment)); | 402 ASSERT(IsPowerOf2(kFrameAlignment)); |
400 and_(esp, -kFrameAlignment); | 403 and_(esp, -kFrameAlignment); |
401 } | 404 } |
402 | 405 |
403 // Patch the saved entry sp. | 406 // Patch the saved entry sp. |
404 mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); | 407 mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); |
405 } | 408 } |
406 | 409 |
407 | 410 |
408 void MacroAssembler::LeaveExitFrame(StackFrame::Type type) { | 411 void MacroAssembler::LeaveExitFrame(StackFrame::Type type) { |
| 412 #ifdef ENABLE_DEBUGGER_SUPPORT |
409 // Restore the memory copy of the registers by digging them out from | 413 // Restore the memory copy of the registers by digging them out from |
410 // the stack. This is needed to allow nested break points. | 414 // the stack. This is needed to allow nested break points. |
411 if (type == StackFrame::EXIT_DEBUG) { | 415 if (type == StackFrame::EXIT_DEBUG) { |
412 // It's okay to clobber register ebx below because we don't need | 416 // It's okay to clobber register ebx below because we don't need |
413 // the function pointer after this. | 417 // the function pointer after this. |
414 const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; | 418 const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; |
415 int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize; | 419 int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize; |
416 lea(ebx, Operand(ebp, kOffset)); | 420 lea(ebx, Operand(ebp, kOffset)); |
417 CopyRegistersFromStackToMemory(ebx, ecx, kJSCallerSaved); | 421 CopyRegistersFromStackToMemory(ebx, ecx, kJSCallerSaved); |
418 } | 422 } |
| 423 #endif |
419 | 424 |
420 // Get the return address from the stack and restore the frame pointer. | 425 // Get the return address from the stack and restore the frame pointer. |
421 mov(ecx, Operand(ebp, 1 * kPointerSize)); | 426 mov(ecx, Operand(ebp, 1 * kPointerSize)); |
422 mov(ebp, Operand(ebp, 0 * kPointerSize)); | 427 mov(ebp, Operand(ebp, 0 * kPointerSize)); |
423 | 428 |
424 // Pop the arguments and the receiver from the caller stack. | 429 // Pop the arguments and the receiver from the caller stack. |
425 lea(esp, Operand(esi, 1 * kPointerSize)); | 430 lea(esp, Operand(esi, 1 * kPointerSize)); |
426 | 431 |
427 // Restore current context from top and clear it in debug mode. | 432 // Restore current context from top and clear it in debug mode. |
428 ExternalReference context_address(Top::k_context_address); | 433 ExternalReference context_address(Top::k_context_address); |
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1037 // Indicate that code has changed. | 1042 // Indicate that code has changed. |
1038 CPU::FlushICache(address_, size_); | 1043 CPU::FlushICache(address_, size_); |
1039 | 1044 |
1040 // Check that the code was patched as expected. | 1045 // Check that the code was patched as expected. |
1041 ASSERT(masm_.pc_ == address_ + size_); | 1046 ASSERT(masm_.pc_ == address_ + size_); |
1042 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); | 1047 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); |
1043 } | 1048 } |
1044 | 1049 |
1045 | 1050 |
1046 } } // namespace v8::internal | 1051 } } // namespace v8::internal |
OLD | NEW |