28 #ifndef V8_DEOPTIMIZER_H_
29 #define V8_DEOPTIMIZER_H_
41 class FrameDescription;
42 class TranslationIterator;
43 class DeoptimizingCodeListNode;
44 class DeoptimizedFrameInfo;
49 : slot_address_(slot_address), val_(val) { }
52 double value()
const {
return val_; }
60 class ArgumentsObjectMaterializationDescriptor
BASE_EMBEDDED {
63 : slot_address_(slot_address), arguments_length_(argc) { }
70 int arguments_length_;
80 virtual void EnterContext(
Context* context) = 0;
82 virtual void VisitFunction(
JSFunction*
function) = 0;
86 virtual void LeaveContext(
Context* context) = 0;
98 #ifdef ENABLE_DEBUGGER_SUPPORT
99 void Iterate(ObjectVisitor* v);
107 #ifdef ENABLE_DEBUGGER_SUPPORT
108 DeoptimizedFrameInfo* deoptimized_frame_info_;
147 #ifdef ENABLE_DEBUGGER_SUPPORT
179 Context* context, OptimizedFunctionVisitor* visitor);
182 JSObject*
object, OptimizedFunctionVisitor* visitor);
193 Code* replacement_code);
200 Code* replacement_code);
206 Code* replacement_code);
213 Code* replacement_code);
218 #ifdef ENABLE_DEBUGGER_SUPPORT
219 void MaterializeHeapNumbersForDebuggerInspectableFrame(
221 uint32_t parameters_size,
223 uint32_t expressions_size,
254 : masm_(masm), type_(type) { }
273 : EntryGenerator(masm, type), count_(count) { }
279 int count()
const {
return count_; }
287 static const int kNumberOfEntries = 16384;
290 JSFunction*
function,
295 Code* optimized_code);
296 void DeleteFrameDescriptions();
298 void DoComputeOutputFrames();
299 void DoComputeOsrOutputFrame();
300 void DoComputeJSFrame(TranslationIterator* iterator,
int frame_index);
301 void DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
303 void DoComputeConstructStubFrame(TranslationIterator* iterator,
305 void DoComputeAccessorStubFrame(TranslationIterator* iterator,
307 bool is_setter_stub_frame);
308 void DoTranslateCommand(TranslationIterator* iterator,
315 bool DoOsrTranslateCommand(TranslationIterator* iterator,
318 unsigned ComputeInputFrameSize()
const;
319 unsigned ComputeFixedSize(JSFunction*
function)
const;
321 unsigned ComputeIncomingArgumentSize(JSFunction*
function)
const;
322 unsigned ComputeOutgoingArgumentSize()
const;
324 Object* ComputeLiteral(
int index)
const;
326 void AddArgumentsObject(intptr_t slot_address,
int argc);
327 void AddArgumentsObjectValue(intptr_t value);
328 void AddDoubleValue(intptr_t slot_address,
double value);
331 static void GenerateDeoptimizationEntries(
332 MacroAssembler* masm,
int count,
BailoutType type);
335 static void HandleWeakDeoptimizedCode(
337 static Code* FindDeoptimizingCodeFromAddress(
Address addr);
338 static void RemoveDeoptimizingCode(Code*
code);
343 void FillInputFrame(
Address tos, JavaScriptFrame* frame);
346 JSFunction* function_;
347 Code* optimized_code_;
348 unsigned bailout_id_;
352 int has_alignment_padding_;
363 List<Object*> deferred_arguments_objects_values_;
364 List<ArgumentsObjectMaterializationDescriptor> deferred_arguments_objects_;
365 List<HeapNumberMaterializationDescriptor> deferred_heap_numbers_;
367 static const int table_entry_size_;
380 void*
operator new(
size_t size, uint32_t frame_size) {
386 void operator delete(
void* pointer, uint32_t frame_size) {
390 void operator delete(
void* description) {
395 ASSERT(static_cast<uint32_t>(frame_size_) == frame_size_);
396 return static_cast<uint32_t
>(frame_size_);
404 return *GetFrameSlotPointer(offset);
408 intptr_t* ptr = GetFrameSlotPointer(offset);
409 #if V8_TARGET_ARCH_MIPS
416 c.u[0] = *
reinterpret_cast<uint32_t*
>(ptr);
417 c.u[1] = *(
reinterpret_cast<uint32_t*
>(ptr) + 1);
420 return *
reinterpret_cast<double*
>(ptr);
425 *GetFrameSlotPointer(offset) = value;
430 return registers_[n];
435 return double_registers_[n];
440 registers_[n] = value;
445 double_registers_[n] = value;
449 void SetTop(intptr_t top) { top_ = top; }
451 intptr_t
GetPc()
const {
return pc_; }
454 intptr_t
GetFp()
const {
return fp_; }
509 static const uint32_t kZapUint32 = 0xbeeddead;
514 uintptr_t frame_size_;
522 StackFrame::Type type_;
530 intptr_t continuation_;
534 intptr_t frame_content_[1];
536 intptr_t* GetFrameSlotPointer(
unsigned offset) {
537 ASSERT(offset < frame_size_);
538 return reinterpret_cast<intptr_t*
>(
542 int ComputeFixedSize();
563 :
buffer_(buffer), index_(index) {
564 ASSERT(index >= 0 && index < buffer->length());
572 for (
int i = 0; i < n; i++) Next();
606 Translation(TranslationBuffer* buffer,
int frame_count,
int jsframe_count,
609 index_(buffer->CurrentIndex()),
612 buffer_->Add(frame_count, zone);
613 buffer_->Add(jsframe_count, zone);
616 int index()
const {
return index_; }
619 void BeginJSFrame(
BailoutId node_id,
int literal_id,
unsigned height);
620 void BeginArgumentsAdaptorFrame(
int literal_id,
unsigned height);
621 void BeginConstructStubFrame(
int literal_id,
unsigned height);
622 void BeginGetterStubFrame(
int literal_id);
623 void BeginSetterStubFrame(
int literal_id);
625 void StoreInt32Register(
Register reg);
626 void StoreUint32Register(
Register reg);
628 void StoreStackSlot(
int index);
629 void StoreInt32StackSlot(
int index);
630 void StoreUint32StackSlot(
int index);
631 void StoreDoubleStackSlot(
int index);
632 void StoreLiteral(
int literal_id);
633 void StoreArgumentsObject(
int args_index,
int args_length);
634 void MarkDuplicate();
638 static int NumberOfOperandsFor(
Opcode opcode);
640 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
641 static const char* StringFor(
Opcode opcode);
645 static const int kSelfLiteralId = -239;
689 : addr_(addr), representation_(representation) { }
692 : literal_(literal), representation_(LITERAL) { }
695 switch (representation_) {
704 return Isolate::Current()->factory()->NewNumberFromInt(value);
713 return Isolate::Current()->factory()->NewNumber(
714 static_cast<double>(value));
720 return Isolate::Current()->factory()->NewNumber(value);
734 int inlined_frame_index,
740 SlotRepresentation representation_;
743 if (slot_index >= 0) {
745 return frame->fp() + offset - (slot_index *
kPointerSize);
748 return frame->fp() + offset - ((slot_index + 1) *
kPointerSize);
752 static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator,
753 DeoptimizationInputData* data,
754 JavaScriptFrame* frame);
756 static void ComputeSlotsForArguments(
757 Vector<SlotRef>* args_slots,
758 TranslationIterator* iterator,
759 DeoptimizationInputData* data,
760 JavaScriptFrame* frame);
764 #ifdef ENABLE_DEBUGGER_SUPPORT
771 class DeoptimizedFrameInfo :
public Malloced {
773 DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
775 bool has_arguments_adaptor,
776 bool has_construct_stub);
777 virtual ~DeoptimizedFrameInfo();
780 void Iterate(ObjectVisitor* v);
783 int parameters_count() {
return parameters_count_; }
786 int expression_count() {
return expression_count_; }
789 JSFunction* GetFunction() {
795 bool HasConstructStub() {
796 return has_construct_stub_;
800 Object* GetParameter(
int index) {
801 ASSERT(0 <= index && index < parameters_count());
802 return parameters_[index];
806 Object* GetExpression(
int index) {
807 ASSERT(0 <= index && index < expression_count());
808 return expression_stack_[index];
811 int GetSourcePosition() {
812 return source_position_;
817 void SetParameter(
int index,
Object* obj) {
818 ASSERT(0 <= index && index < parameters_count());
819 parameters_[index] = obj;
823 void SetExpression(
int index,
Object* obj) {
824 ASSERT(0 <= index && index < expression_count());
825 expression_stack_[index] = obj;
828 JSFunction* function_;
829 bool has_construct_stub_;
830 int parameters_count_;
831 int expression_count_;
833 Object** expression_stack_;
834 int source_position_;
836 friend class Deoptimizer;
842 #endif // V8_DEOPTIMIZER_H_
static int registers_offset()
DeoptimizingCodeListNode * next() const
static const int kLastParameterOffset
static Object *& Object_at(Address addr)
Handle< Code > code() const
HeapNumberMaterializationDescriptor(Address slot_address, double val)
static Smi * FromInt(int value)
unsigned GetOffsetFromSlotIndex(int slot_index)
static double & double_at(Address addr)
void SetFrameSlot(unsigned offset, intptr_t value)
static void RevertStackCheckCode(Code *unoptimized_code, Code *check_code, Code *replacement_code)
static void ComputeOutputFrames(Deoptimizer *deoptimizer)
Address slot_address() const
virtual void GeneratePrologue()
void SetState(Smi *state)
static const int kNumAllocatableRegisters
SlotRef(Address addr, SlotRepresentation representation)
#define ASSERT(condition)
static void DeoptimizeFunction(JSFunction *function)
static void DeoptimizeAll()
Handle< Object > GetValue()
double GetDoubleRegister(unsigned n) const
intptr_t GetContext() const
int arguments_length() const
void MaterializeHeapObjects(JavaScriptFrameIterator *it)
void SetFrameType(StackFrame::Type type)
StringInputBuffer *const buffer_
DeoptimizingCodeListNode(Code *code)
static const int kNumRegisters
static int double_registers_offset()
MacroAssembler * masm() const
static int frame_content_offset()
int ComputeParametersCount()
JSFunction * GetFunction() const
static void DeoptimizeGlobalObject(JSObject *object)
static int output_offset()
TableEntryGenerator(MacroAssembler *masm, BailoutType type, int count)
#define OFFSET_OF(type, field)
static bool IsValid(intptr_t value)
Translation(TranslationBuffer *buffer, int frame_count, int jsframe_count, Zone *zone)
static int state_offset()
static int32_t & int32_at(Address addr)
EntryGenerator(MacroAssembler *masm, BailoutType type)
void SetRegister(unsigned n, intptr_t value)
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
static int GetDeoptimizedCodeCount(Isolate *isolate)
void set_next(DeoptimizingCodeListNode *next)
unsigned GetExpressionCount()
static void EnsureRelocSpaceForLazyDeoptimization(Handle< Code > code)
static int GetOutputInfo(DeoptimizationOutputData *data, BailoutId node_id, SharedFunctionInfo *shared)
static void ReplaceCodeForRelatedFunctions(JSFunction *function, Code *code)
static void PatchStackCheckCode(Code *unoptimized_code, Code *check_code, Code *replacement_code)
~DeoptimizingCodeListNode()
uint32_t GetFrameSize() const
kPropertyAccessorsOffset kNamedPropertyHandlerOffset kInstanceTemplateOffset kAccessCheckInfoOffset kEvalFrominstructionsOffsetOffset kInstanceClassNameOffset kHiddenPrototypeBit kReadOnlyPrototypeBit kIsTopLevelBit kAllowLazyCompilation kUsesArguments formal_parameter_count
static void VisitAllOptimizedFunctionsForContext(Context *context, OptimizedFunctionVisitor *visitor)
void SetContinuation(intptr_t pc)
virtual ~OptimizedFunctionVisitor()
static int frame_size_offset()
static int output_count_offset()
static void RevertStackCheckCodeAt(Code *unoptimized_code, Address pc_after, Code *check_code, Code *replacement_code)
intptr_t GetFrameSlot(unsigned offset)
TranslationBuffer(Zone *zone)
JavaScriptFrameIteratorTemp< StackFrameIterator > JavaScriptFrameIterator
friend class DeoptimizedFrameInfo
static Address GetDeoptimizationEntry(int id, BailoutType type)
TranslationIterator(ByteArray *buffer, int index)
static Deoptimizer * Grab(Isolate *isolate)
static const int kNotDeoptimizationEntry
static Handle< T > null()
friend class FrameDescription
StackFrame::Type GetFrameType() const
virtual void GeneratePrologue()
double GetDoubleFrameSlot(unsigned offset)
FrameDescription(uint32_t frame_size, JSFunction *function)
virtual ~EntryGenerator()
static void VisitAllOptimizedFunctions(OptimizedFunctionVisitor *visitor)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
void SetContext(intptr_t context)
static uint32_t & uint32_at(Address addr)
int ConvertJSFrameIndexToFrameIndex(int jsframe_index)
static void VisitAllOptimizedFunctionsForGlobalObject(JSObject *object, OptimizedFunctionVisitor *visitor)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
intptr_t GetRegister(unsigned n) const
void SetDoubleRegister(unsigned n, double value)
int jsframe_count() const
static const int kLocal0Offset
static const int kMaxValue
static int GetDeoptimizationId(Address addr, BailoutType type)
ArgumentsObjectMaterializationDescriptor(Address slot_address, int argc)
static void PatchStackCheckCodeAt(Code *unoptimized_code, Address pc_after, Code *check_code, Code *replacement_code)
void SetTop(intptr_t top)
static int continuation_offset()
static int has_alignment_padding_offset()
static Deoptimizer * New(JSFunction *function, BailoutType type, unsigned bailout_id, Address from, int fp_to_sp_delta, Isolate *isolate)
static int input_offset()
Object * GetExpression(int index)
Object * GetParameter(int index)