| OLD | NEW | 
|    1 // Copyright 2012 the V8 project authors. All rights reserved. |    1 // Copyright 2012 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 17 matching lines...) Expand all  Loading... | 
|   28 #include "v8.h" |   28 #include "v8.h" | 
|   29  |   29  | 
|   30 #include "codegen.h" |   30 #include "codegen.h" | 
|   31 #include "deoptimizer.h" |   31 #include "deoptimizer.h" | 
|   32 #include "full-codegen.h" |   32 #include "full-codegen.h" | 
|   33 #include "safepoint-table.h" |   33 #include "safepoint-table.h" | 
|   34  |   34  | 
|   35 namespace v8 { |   35 namespace v8 { | 
|   36 namespace internal { |   36 namespace internal { | 
|   37  |   37  | 
|   38 const int Deoptimizer::table_entry_size_ = 16; |   38 const int Deoptimizer::table_entry_size_ = 12; | 
|   39  |   39  | 
|   40  |   40  | 
|   41 int Deoptimizer::patch_size() { |   41 int Deoptimizer::patch_size() { | 
|   42   const int kCallInstructionSizeInWords = 3; |   42   const int kCallInstructionSizeInWords = 3; | 
|   43   return kCallInstructionSizeInWords * Assembler::kInstrSize; |   43   return kCallInstructionSizeInWords * Assembler::kInstrSize; | 
|   44 } |   44 } | 
|   45  |   45  | 
|   46  |   46  | 
|   47 void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList( |   47 void Deoptimizer::DeoptimizeFunctionWithPreparedFunctionList( | 
|   48     JSFunction* function) { |   48     JSFunction* function) { | 
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  458   // TODO(1588) Note that using pc with stm is deprecated, so we should perhaps |  458   // TODO(1588) Note that using pc with stm is deprecated, so we should perhaps | 
|  459   // handle this a bit differently. |  459   // handle this a bit differently. | 
|  460   __ stm(db_w, sp, restored_regs  | sp.bit() | lr.bit() | pc.bit()); |  460   __ stm(db_w, sp, restored_regs  | sp.bit() | lr.bit() | pc.bit()); | 
|  461  |  461  | 
|  462   const int kSavedRegistersAreaSize = |  462   const int kSavedRegistersAreaSize = | 
|  463       (kNumberOfRegisters * kPointerSize) + kDoubleRegsSize; |  463       (kNumberOfRegisters * kPointerSize) + kDoubleRegsSize; | 
|  464  |  464  | 
|  465   // Get the bailout id from the stack. |  465   // Get the bailout id from the stack. | 
|  466   __ ldr(r2, MemOperand(sp, kSavedRegistersAreaSize)); |  466   __ ldr(r2, MemOperand(sp, kSavedRegistersAreaSize)); | 
|  467  |  467  | 
|  468   // Get the address of the location in the code object if possible (r3) (return |  468   // Get the address of the location in the code object (r3) (return | 
|  469   // address for lazy deoptimization) and compute the fp-to-sp delta in |  469   // address for lazy deoptimization) and compute the fp-to-sp delta in | 
|  470   // register r4. |  470   // register r4. | 
|  471   if (type() == EAGER || type() == SOFT) { |  471   __ mov(r3, lr); | 
|  472     __ mov(r3, Operand::Zero()); |  472   // Correct one word for bailout id. | 
|  473     // Correct one word for bailout id. |  473   __ add(r4, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize))); | 
|  474     __ add(r4, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize))); |  | 
|  475   } else if (type() == OSR) { |  | 
|  476     __ mov(r3, lr); |  | 
|  477     // Correct one word for bailout id. |  | 
|  478     __ add(r4, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize))); |  | 
|  479   } else { |  | 
|  480     __ mov(r3, lr); |  | 
|  481     // Correct two words for bailout id and return address. |  | 
|  482     __ add(r4, sp, Operand(kSavedRegistersAreaSize + (2 * kPointerSize))); |  | 
|  483   } |  | 
|  484   __ sub(r4, fp, r4); |  474   __ sub(r4, fp, r4); | 
|  485  |  475  | 
|  486   // Allocate a new deoptimizer object. |  476   // Allocate a new deoptimizer object. | 
|  487   // Pass four arguments in r0 to r3 and fifth argument on stack. |  477   // Pass four arguments in r0 to r3 and fifth argument on stack. | 
|  488   __ PrepareCallCFunction(6, r5); |  478   __ PrepareCallCFunction(6, r5); | 
|  489   __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |  479   __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 
|  490   __ mov(r1, Operand(type()));  // bailout type, |  480   __ mov(r1, Operand(type()));  // bailout type, | 
|  491   // r2: bailout id already loaded. |  481   // r2: bailout id already loaded. | 
|  492   // r3: code address or 0 already loaded. |  482   // r3: code address or 0 already loaded. | 
|  493   __ str(r4, MemOperand(sp, 0 * kPointerSize));  // Fp-to-sp delta. |  483   __ str(r4, MemOperand(sp, 0 * kPointerSize));  // Fp-to-sp delta. | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|  514   // Copy VFP registers to |  504   // Copy VFP registers to | 
|  515   // double_registers_[DoubleRegister::kMaxNumAllocatableRegisters] |  505   // double_registers_[DoubleRegister::kMaxNumAllocatableRegisters] | 
|  516   int double_regs_offset = FrameDescription::double_registers_offset(); |  506   int double_regs_offset = FrameDescription::double_registers_offset(); | 
|  517   for (int i = 0; i < DwVfpRegister::kMaxNumAllocatableRegisters; ++i) { |  507   for (int i = 0; i < DwVfpRegister::kMaxNumAllocatableRegisters; ++i) { | 
|  518     int dst_offset = i * kDoubleSize + double_regs_offset; |  508     int dst_offset = i * kDoubleSize + double_regs_offset; | 
|  519     int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize; |  509     int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize; | 
|  520     __ vldr(d0, sp, src_offset); |  510     __ vldr(d0, sp, src_offset); | 
|  521     __ vstr(d0, r1, dst_offset); |  511     __ vstr(d0, r1, dst_offset); | 
|  522   } |  512   } | 
|  523  |  513  | 
|  524   // Remove the bailout id, eventually return address, and the saved registers |  514   // Remove the bailout id and the saved registers from the stack. | 
|  525   // from the stack. |  515   __ add(sp, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize))); | 
|  526   if (type() == EAGER || type() == SOFT || type() == OSR) { |  | 
|  527     __ add(sp, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize))); |  | 
|  528   } else { |  | 
|  529     __ add(sp, sp, Operand(kSavedRegistersAreaSize + (2 * kPointerSize))); |  | 
|  530   } |  | 
|  531  |  516  | 
|  532   // Compute a pointer to the unwinding limit in register r2; that is |  517   // Compute a pointer to the unwinding limit in register r2; that is | 
|  533   // the first stack slot not part of the input frame. |  518   // the first stack slot not part of the input frame. | 
|  534   __ ldr(r2, MemOperand(r1, FrameDescription::frame_size_offset())); |  519   __ ldr(r2, MemOperand(r1, FrameDescription::frame_size_offset())); | 
|  535   __ add(r2, r2, sp); |  520   __ add(r2, r2, sp); | 
|  536  |  521  | 
|  537   // Unwind the stack down to - but not including - the unwinding |  522   // Unwind the stack down to - but not including - the unwinding | 
|  538   // limit and copy the contents of the activation frame to the input |  523   // limit and copy the contents of the activation frame to the input | 
|  539   // frame description. |  524   // frame description. | 
|  540   __ add(r3,  r1, Operand(FrameDescription::frame_content_offset())); |  525   __ add(r3,  r1, Operand(FrameDescription::frame_content_offset())); | 
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  629  |  614  | 
|  630   __ pop(ip);  // remove pc |  615   __ pop(ip);  // remove pc | 
|  631   __ pop(r7);  // get continuation, leave pc on stack |  616   __ pop(r7);  // get continuation, leave pc on stack | 
|  632   __ pop(lr); |  617   __ pop(lr); | 
|  633   __ Jump(r7); |  618   __ Jump(r7); | 
|  634   __ stop("Unreachable."); |  619   __ stop("Unreachable."); | 
|  635 } |  620 } | 
|  636  |  621  | 
|  637  |  622  | 
|  638 void Deoptimizer::TableEntryGenerator::GeneratePrologue() { |  623 void Deoptimizer::TableEntryGenerator::GeneratePrologue() { | 
|  639   // Create a sequence of deoptimization entries. Note that any |  624   // Create a sequence of deoptimization entries. | 
|  640   // registers may be still live. |  625   // Note that registers are still live when jumping to an entry. | 
|  641   Label done; |  626   Label done; | 
|  642   for (int i = 0; i < count(); i++) { |  627   for (int i = 0; i < count(); i++) { | 
|  643     int start = masm()->pc_offset(); |  628     int start = masm()->pc_offset(); | 
|  644     USE(start); |  629     USE(start); | 
|  645     if (type() == EAGER || type() == SOFT) { |  | 
|  646       __ nop(); |  | 
|  647     } else { |  | 
|  648       // Emulate ia32 like call by pushing return address to stack. |  | 
|  649       __ push(lr); |  | 
|  650     } |  | 
|  651     __ mov(ip, Operand(i)); |  630     __ mov(ip, Operand(i)); | 
|  652     __ push(ip); |  631     __ push(ip); | 
|  653     __ b(&done); |  632     __ b(&done); | 
|  654     ASSERT(masm()->pc_offset() - start == table_entry_size_); |  633     ASSERT(masm()->pc_offset() - start == table_entry_size_); | 
|  655   } |  634   } | 
|  656   __ bind(&done); |  635   __ bind(&done); | 
|  657 } |  636 } | 
|  658  |  637  | 
|  659 #undef __ |  638 #undef __ | 
|  660  |  639  | 
|  661 } }  // namespace v8::internal |  640 } }  // namespace v8::internal | 
| OLD | NEW |