28 #ifndef V8_DEOPTIMIZER_H_
29 #define V8_DEOPTIMIZER_H_
42 static inline double read_double_value(
Address p) {
43 #ifdef V8_HOST_CAN_READ_UNALIGNED
45 #else // V8_HOST_CAN_READ_UNALIGNED
52 c.u[0] = *
reinterpret_cast<uint32_t*
>(p);
53 c.u[1] = *
reinterpret_cast<uint32_t*
>(p + 4);
55 #endif // V8_HOST_CAN_READ_UNALIGNED
59 class FrameDescription;
60 class TranslationIterator;
61 class DeoptimizedFrameInfo;
67 : destination_(destination), value_(value) { }
70 double value()
const {
return value_; }
81 Address slot_address,
int frame,
int length,
int duplicate,
bool is_args)
82 : slot_address_(slot_address),
83 jsframe_index_(frame),
84 object_length_(length),
85 duplicate_object_(duplicate),
86 is_arguments_(is_args) { }
96 slot_address_ =
reinterpret_cast<Address>(slot);
103 int duplicate_object_;
114 virtual void EnterContext(
Context* context) = 0;
116 virtual void VisitFunction(
JSFunction*
function) = 0;
120 virtual void LeaveContext(
Context* context) = 0;
172 #ifdef ENABLE_DEBUGGER_SUPPORT
215 #ifdef ENABLE_DEBUGGER_SUPPORT
216 void MaterializeHeapNumbersForDebuggerInspectableFrame(
218 uint32_t parameters_size,
220 uint32_t expressions_size,
264 : masm_(masm), type_(type) { }
284 : EntryGenerator(masm, type), count_(count) { }
290 int count()
const {
return count_; }
306 static const int kMinNumberOfEntries = 64;
307 static const int kMaxNumberOfEntries = 16384;
315 Code* optimized_code);
317 void PrintFunctionName();
318 void DeleteFrameDescriptions();
320 void DoComputeOutputFrames();
321 void DoComputeJSFrame(TranslationIterator* iterator,
int frame_index);
322 void DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
324 void DoComputeConstructStubFrame(TranslationIterator* iterator,
326 void DoComputeAccessorStubFrame(TranslationIterator* iterator,
328 bool is_setter_stub_frame);
329 void DoComputeCompiledStubFrame(TranslationIterator* iterator,
332 void DoTranslateObject(TranslationIterator* iterator,
336 void DoTranslateCommand(TranslationIterator* iterator,
340 unsigned ComputeInputFrameSize()
const;
341 unsigned ComputeFixedSize(
JSFunction*
function)
const;
343 unsigned ComputeIncomingArgumentSize(
JSFunction*
function)
const;
344 unsigned ComputeOutgoingArgumentSize()
const;
346 Object* ComputeLiteral(
int index)
const;
348 void AddObjectStart(intptr_t slot_address,
int argc,
bool is_arguments);
349 void AddObjectDuplication(intptr_t slot,
int object_index);
350 void AddObjectTaggedValue(intptr_t value);
351 void AddObjectDoubleValue(
double value);
352 void AddDoubleValue(intptr_t slot_address,
double value);
354 bool ArgumentsObjectIsAdapted(
int object_index) {
355 ObjectMaterializationDescriptor desc = deferred_objects_.
at(object_index);
356 int reverse_jsframe_index = jsframe_count_ - desc.jsframe_index() - 1;
357 return jsframe_has_adapted_arguments_[reverse_jsframe_index];
361 ObjectMaterializationDescriptor desc = deferred_objects_.
at(object_index);
362 int reverse_jsframe_index = jsframe_count_ - desc.jsframe_index() - 1;
363 return jsframe_functions_[reverse_jsframe_index];
367 Handle<Object> MaterializeNextHeapObject();
368 Handle<Object> MaterializeNextValue();
370 static void GenerateDeoptimizationEntries(
371 MacroAssembler* masm,
int count,
BailoutType type);
374 static void MarkAllCodeForContext(Context* native_context);
377 static void VisitAllOptimizedFunctionsForContext(
378 Context* context, OptimizedFunctionVisitor* visitor);
381 static void DeoptimizeMarkedCodeForContext(Context* native_context);
384 static void PatchCodeForDeoptimization(Isolate*
isolate, Code*
code);
389 Code* FindDeoptimizingCode(
Address addr);
394 void FillInputFrame(
Address tos, JavaScriptFrame* frame);
399 CodeStubInterfaceDescriptor* desc);
407 bool HasAlignmentPadding(JSFunction*
function);
411 Code* NotifyStubFailureBuiltin();
414 JSFunction* function_;
415 Code* compiled_code_;
416 unsigned bailout_id_;
420 int has_alignment_padding_;
432 List<Object*> deferred_objects_tagged_values_;
433 List<HeapNumberMaterializationDescriptor<int> >
434 deferred_objects_double_values_;
435 List<ObjectMaterializationDescriptor> deferred_objects_;
436 List<HeapNumberMaterializationDescriptor<Address> > deferred_heap_numbers_;
440 Handle<FixedArray> previously_materialized_objects_;
441 int prev_materialized_count_;
444 List<Handle<JSFunction> > jsframe_functions_;
445 List<bool> jsframe_has_adapted_arguments_;
448 List<Handle<Object> >* materialized_values_;
449 List<Handle<Object> >* materialized_objects_;
450 int materialization_value_index_;
451 int materialization_object_index_;
457 CodeTracer::Scope* trace_scope_;
459 static const int table_entry_size_;
471 void*
operator new(
size_t size, uint32_t frame_size) {
477 void operator delete(
void* pointer, uint32_t frame_size) {
481 void operator delete(
void* description) {
486 ASSERT(static_cast<uint32_t>(frame_size_) == frame_size_);
487 return static_cast<uint32_t
>(frame_size_);
495 return *GetFrameSlotPointer(offset);
499 intptr_t* ptr = GetFrameSlotPointer(offset);
500 return read_double_value(reinterpret_cast<Address>(ptr));
504 *GetFrameSlotPointer(offset) = value;
523 return registers_[n];
528 return double_registers_[n];
533 registers_[n] = value;
538 double_registers_[n] = value;
542 void SetTop(intptr_t top) { top_ = top; }
544 intptr_t
GetPc()
const {
return pc_; }
547 intptr_t
GetFp()
const {
return fp_; }
555 constant_pool_ = constant_pool;
607 static const uint32_t kZapUint32 = 0xbeeddead;
612 uintptr_t frame_size_;
620 intptr_t constant_pool_;
626 intptr_t continuation_;
630 intptr_t frame_content_[1];
632 intptr_t* GetFrameSlotPointer(
unsigned offset) {
633 ASSERT(offset < frame_size_);
634 return reinterpret_cast<intptr_t*
>(
638 int ComputeFixedSize();
647 #ifdef ENABLE_DEBUGGER_SUPPORT
648 void Iterate(ObjectVisitor* v);
656 #ifdef ENABLE_DEBUGGER_SUPPORT
657 DeoptimizedFrameInfo* deoptimized_frame_info_;
685 : buffer_(buffer), index_(index) {
686 ASSERT(index >= 0 && index < buffer->length());
691 bool HasNext()
const {
return index_ < buffer_->length(); }
694 for (
int i = 0; i < n; i++) Next();
703 #define TRANSLATION_OPCODE_LIST(V) \
706 V(CONSTRUCT_STUB_FRAME) \
707 V(GETTER_STUB_FRAME) \
708 V(SETTER_STUB_FRAME) \
709 V(ARGUMENTS_ADAPTOR_FRAME) \
710 V(COMPILED_STUB_FRAME) \
711 V(DUPLICATED_OBJECT) \
712 V(ARGUMENTS_OBJECT) \
719 V(INT32_STACK_SLOT) \
720 V(UINT32_STACK_SLOT) \
721 V(DOUBLE_STACK_SLOT) \
727 #define DECLARE_TRANSLATION_OPCODE_ENUM(item) item,
732 #undef DECLARE_TRANSLATION_OPCODE_ENUM
734 Translation(TranslationBuffer* buffer,
int frame_count,
int jsframe_count,
737 index_(buffer->CurrentIndex()),
739 buffer_->Add(BEGIN, zone);
740 buffer_->Add(frame_count, zone);
741 buffer_->Add(jsframe_count, zone);
744 int index()
const {
return index_; }
747 void BeginJSFrame(
BailoutId node_id,
int literal_id,
unsigned height);
748 void BeginCompiledStubFrame();
749 void BeginArgumentsAdaptorFrame(
int literal_id,
unsigned height);
750 void BeginConstructStubFrame(
int literal_id,
unsigned height);
751 void BeginGetterStubFrame(
int literal_id);
752 void BeginSetterStubFrame(
int literal_id);
753 void BeginArgumentsObject(
int args_length);
754 void BeginCapturedObject(
int length);
755 void DuplicateObject(
int object_index);
757 void StoreInt32Register(
Register reg);
758 void StoreUint32Register(
Register reg);
760 void StoreStackSlot(
int index);
761 void StoreInt32StackSlot(
int index);
762 void StoreUint32StackSlot(
int index);
763 void StoreDoubleStackSlot(
int index);
764 void StoreLiteral(
int literal_id);
765 void StoreArgumentsObject(
bool args_known,
int args_index,
int args_length);
769 static int NumberOfOperandsFor(
Opcode opcode);
771 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
772 static const char* StringFor(
Opcode opcode);
776 static const int kSelfLiteralId = -239;
779 TranslationBuffer* buffer_;
808 : addr_(addr), representation_(representation) { }
811 : literal_(literal, isolate), representation_(LITERAL) { }
815 slot.representation_ = ARGUMENTS_OBJECT;
816 slot.deferred_object_length_ = length;
822 slot.representation_ = DEFERRED_OBJECT;
823 slot.deferred_object_length_ = length;
831 slot.representation_ = DUPLICATE_OBJECT;
832 slot.duplicate_object_id_ = id;
837 if (representation_ == DEFERRED_OBJECT ||
838 representation_ == ARGUMENTS_OBJECT) {
839 return deferred_object_length_;
852 SlotRepresentation representation_;
853 int deferred_object_length_;
854 int duplicate_object_id_;
860 JavaScriptFrame* frame,
861 int inlined_frame_index,
864 void Prepare(
Isolate* isolate);
873 int prev_materialized_count_;
878 int first_slot_index_;
880 static SlotRef ComputeSlotForNextArgument(
882 TranslationIterator* iterator,
889 if (slot_index >= 0) {
891 return frame->fp() + offset - (slot_index *
kPointerSize);
894 return frame->fp() + offset - ((slot_index + 1) *
kPointerSize);
898 Handle<Object> GetDeferredObject(Isolate* isolate);
911 Isolate* isolate() {
return isolate_; }
918 List<Address> frame_fps_;
922 #ifdef ENABLE_DEBUGGER_SUPPORT
929 class DeoptimizedFrameInfo :
public Malloced {
931 DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
933 bool has_arguments_adaptor,
934 bool has_construct_stub);
935 virtual ~DeoptimizedFrameInfo();
938 void Iterate(ObjectVisitor* v);
941 int parameters_count() {
return parameters_count_; }
944 int expression_count() {
return expression_count_; }
947 JSFunction* GetFunction() {
953 bool HasConstructStub() {
954 return has_construct_stub_;
958 Object* GetParameter(
int index) {
959 ASSERT(0 <= index && index < parameters_count());
960 return parameters_[index];
964 Object* GetExpression(
int index) {
965 ASSERT(0 <= index && index < expression_count());
966 return expression_stack_[index];
969 int GetSourcePosition() {
970 return source_position_;
975 void SetParameter(
int index,
Object*
obj) {
976 ASSERT(0 <= index && index < parameters_count());
977 parameters_[index] =
obj;
981 void SetExpression(
int index,
Object* obj) {
982 ASSERT(0 <= index && index < expression_count());
983 expression_stack_[index] =
obj;
986 JSFunction* function_;
987 bool has_construct_stub_;
988 int parameters_count_;
989 int expression_count_;
991 Object** expression_stack_;
992 int source_position_;
994 friend class Deoptimizer;
1000 #endif // V8_DEOPTIMIZER_H_
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
static int registers_offset()
void SetCallerPc(unsigned offset, intptr_t value)
static const int kLastParameterOffset
SlotRepresentation Representation()
static const int kBailoutTypesWithCodeEntry
static void EnsureCodeForDeoptimizationEntry(Isolate *isolate, BailoutType type, int max_entry_id)
int duplicate_object() const
Deoptimizer::BailoutType bailout_type
unsigned GetOffsetFromSlotIndex(int slot_index)
static double & double_at(Address addr)
void SetFrameSlot(unsigned offset, intptr_t value)
static void ComputeOutputFrames(Deoptimizer *deoptimizer)
Address slot_address() const
SlotRef(Isolate *isolate, Object *literal)
static SlotRef NewDeferredObject(int length)
BailoutType bailout_type() const
kSerializedDataOffset Object
virtual void GeneratePrologue()
void SetState(Smi *state)
TypeImpl< ZoneTypeConfig > Type
DeoptimizerData(MemoryAllocator *allocator)
HeapNumberMaterializationDescriptor(T destination, double value)
static const char * MessageFor(BailoutType type)
SlotRef(Address addr, SlotRepresentation representation)
Isolate * isolate() const
#define ASSERT(condition)
static void DeoptimizeFunction(JSFunction *function)
void patch_slot_address(intptr_t slot)
void SetConstantPool(intptr_t constant_pool)
double GetDoubleRegister(unsigned n) const
intptr_t GetContext() const
void MaterializeHeapObjects(JavaScriptFrameIterator *it)
void SetFrameType(StackFrame::Type type)
static bool TraceEnabledFor(BailoutType deopt_type, StackFrame::Type frame_type)
static SlotRef NewDuplicateObject(int id)
static const int kNumRegisters
static int double_registers_offset()
MacroAssembler * masm() const
static void VisitAllOptimizedFunctions(Isolate *isolate, OptimizedFunctionVisitor *visitor)
static int frame_content_offset()
int ComputeParametersCount()
JSFunction * GetFunction() const
Handle< Code > compiled_code() const
static void DeoptimizeGlobalObject(JSObject *object)
static int output_offset()
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization 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 VFP3 instructions if available enable use of NEON instructions if 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 d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_string(expose_natives_as
Isolate * isolate() const
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object size
TableEntryGenerator(MacroAssembler *masm, BailoutType type, int count)
#define OFFSET_OF(type, field)
static Address GetDeoptimizationEntry(Isolate *isolate, int id, BailoutType type, GetEntryMode mode=ENSURE_ENTRY_CODE)
Translation(TranslationBuffer *buffer, int frame_count, int jsframe_count, Zone *zone)
static int state_offset()
static int GetDeoptimizationId(Isolate *isolate, Address addr, BailoutType type)
EntryGenerator(MacroAssembler *masm, BailoutType type)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
void SetRegister(unsigned n, intptr_t value)
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
static const int kMaxNumRegisters
static void DeoptimizeAll(Isolate *isolate)
static int GetDeoptimizedCodeCount(Isolate *isolate)
unsigned GetExpressionCount()
static void EnsureRelocSpaceForLazyDeoptimization(Handle< Code > code)
static int GetOutputInfo(DeoptimizationOutputData *data, BailoutId node_id, SharedFunctionInfo *shared)
bool is_arguments() const
ObjectMaterializationDescriptor(Address slot_address, int frame, int length, int duplicate, bool is_args)
void SetCallerConstantPool(unsigned offset, intptr_t value)
static SlotRef NewArgumentsObject(int length)
uint32_t GetFrameSize() const
#define T(name, string, precedence)
void SetContinuation(intptr_t pc)
virtual ~OptimizedFunctionVisitor()
JumpTableEntry(Address entry, Deoptimizer::BailoutType type, bool frame)
static int frame_size_offset()
static int output_count_offset()
int jsframe_index() const
MaterializedObjectStore(Isolate *isolate)
intptr_t GetFrameSlot(unsigned offset)
TranslationBuffer(Zone *zone)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function info
friend class DeoptimizedFrameInfo
TranslationIterator(ByteArray *buffer, int index)
static Deoptimizer * Grab(Isolate *isolate)
static const int kNotDeoptimizationEntry
friend class FrameDescription
StackFrame::Type GetFrameType() const
kInstanceClassNameOffset kNeedsAccessCheckBit kRemovePrototypeBit kIsExpressionBit kAllowLazyCompilation kUsesArguments formal_parameter_count
#define DECLARE_TRANSLATION_OPCODE_ENUM(item)
virtual void GeneratePrologue()
PerThreadAssertScopeDebugOnly< HEAP_ALLOCATION_ASSERT, false > DisallowHeapAllocation
double GetDoubleFrameSlot(unsigned offset)
FrameDescription(uint32_t frame_size, JSFunction *function)
virtual ~EntryGenerator()
void SetContext(intptr_t context)
static size_t GetMaxDeoptTableSize()
int ConvertJSFrameIndexToFrameIndex(int jsframe_index)
intptr_t GetRegister(unsigned n) const
static void DeoptimizeMarkedCode(Isolate *isolate)
void SetDoubleRegister(unsigned n, double value)
int object_length() const
int jsframe_count() const
static const int kLocal0Offset
void SetCallerFp(unsigned offset, intptr_t value)
#define TRANSLATION_OPCODE_LIST(V)
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()
intptr_t GetConstantPool() const
Object * GetExpression(int index)
Object * GetParameter(int index)