| 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 |