blob: 612d5f6ecf466d0902c032d491b3fd661c48efe8 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Ben Murdochb0fe1622011-05-05 13:52:32 +01004
5#ifndef V8_DEOPTIMIZER_H_
6#define V8_DEOPTIMIZER_H_
7
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/v8.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +01009
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include "src/allocation.h"
11#include "src/macro-assembler.h"
12#include "src/zone-inl.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010013
14
15namespace v8 {
16namespace internal {
17
Ben Murdochb8a8cc12014-11-26 15:28:44 +000018
19static inline double read_double_value(Address p) {
20 double d;
21 memcpy(&d, p, sizeof(d));
22 return d;
23}
24
25
Ben Murdochb0fe1622011-05-05 13:52:32 +010026class FrameDescription;
27class TranslationIterator;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000028class DeoptimizedFrameInfo;
Ben Murdochb0fe1622011-05-05 13:52:32 +010029
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030template<typename T>
Ben Murdoch8b112d22011-06-08 16:22:53 +010031class HeapNumberMaterializationDescriptor BASE_EMBEDDED {
Ben Murdochb0fe1622011-05-05 13:52:32 +010032 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033 HeapNumberMaterializationDescriptor(T destination, double value)
34 : destination_(destination), value_(value) { }
35
36 T destination() const { return destination_; }
37 double value() const { return value_; }
38
39 private:
40 T destination_;
41 double value_;
42};
43
44
45class ObjectMaterializationDescriptor BASE_EMBEDDED {
46 public:
47 ObjectMaterializationDescriptor(
48 Address slot_address, int frame, int length, int duplicate, bool is_args)
49 : slot_address_(slot_address),
50 jsframe_index_(frame),
51 object_length_(length),
52 duplicate_object_(duplicate),
53 is_arguments_(is_args) { }
Ben Murdoch8b112d22011-06-08 16:22:53 +010054
55 Address slot_address() const { return slot_address_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000056 int jsframe_index() const { return jsframe_index_; }
57 int object_length() const { return object_length_; }
58 int duplicate_object() const { return duplicate_object_; }
59 bool is_arguments() const { return is_arguments_; }
60
61 // Only used for allocated receivers in DoComputeConstructStubFrame.
62 void patch_slot_address(intptr_t slot) {
63 slot_address_ = reinterpret_cast<Address>(slot);
64 }
Ben Murdochb0fe1622011-05-05 13:52:32 +010065
66 private:
Ben Murdoch8b112d22011-06-08 16:22:53 +010067 Address slot_address_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000068 int jsframe_index_;
69 int object_length_;
70 int duplicate_object_;
71 bool is_arguments_;
Ben Murdochb0fe1622011-05-05 13:52:32 +010072};
73
74
75class OptimizedFunctionVisitor BASE_EMBEDDED {
76 public:
77 virtual ~OptimizedFunctionVisitor() {}
78
79 // Function which is called before iteration of any optimized functions
Ben Murdochb8a8cc12014-11-26 15:28:44 +000080 // from given native context.
Ben Murdochb0fe1622011-05-05 13:52:32 +010081 virtual void EnterContext(Context* context) = 0;
82
83 virtual void VisitFunction(JSFunction* function) = 0;
84
85 // Function which is called after iteration of all optimized functions
Ben Murdochb8a8cc12014-11-26 15:28:44 +000086 // from given native context.
Ben Murdochb0fe1622011-05-05 13:52:32 +010087 virtual void LeaveContext(Context* context) = 0;
88};
89
90
91class Deoptimizer : public Malloced {
92 public:
93 enum BailoutType {
94 EAGER,
95 LAZY,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000096 SOFT,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000097 // This last bailout type is not really a bailout, but used by the
98 // debugger to deoptimize stack frames to allow inspection.
99 DEBUGGER
Ben Murdochb0fe1622011-05-05 13:52:32 +0100100 };
101
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000102 static const int kBailoutTypesWithCodeEntry = SOFT + 1;
103
104 struct Reason {
105 Reason(int r, const char* m, const char* d)
106 : raw_position(r), mnemonic(m), detail(d) {}
107
108 bool operator==(const Reason& other) const {
109 return raw_position == other.raw_position &&
110 CStringEquals(mnemonic, other.mnemonic) &&
111 CStringEquals(detail, other.detail);
112 }
113
114 bool operator!=(const Reason& other) const { return !(*this == other); }
115
116 int raw_position;
117 const char* mnemonic;
118 const char* detail;
119 };
120
121 struct JumpTableEntry : public ZoneObject {
122 inline JumpTableEntry(Address entry, const Reason& the_reason,
123 Deoptimizer::BailoutType type, bool frame)
124 : label(),
125 address(entry),
126 reason(the_reason),
127 bailout_type(type),
128 needs_frame(frame) {}
129
130 bool IsEquivalentTo(const JumpTableEntry& other) const {
131 return address == other.address && bailout_type == other.bailout_type &&
132 needs_frame == other.needs_frame &&
133 (!FLAG_trace_deopt || reason == other.reason);
134 }
135
136 Label label;
137 Address address;
138 Reason reason;
139 Deoptimizer::BailoutType bailout_type;
140 bool needs_frame;
141 };
142
143 static bool TraceEnabledFor(BailoutType deopt_type,
144 StackFrame::Type frame_type);
145 static const char* MessageFor(BailoutType type);
146
Ben Murdochb0fe1622011-05-05 13:52:32 +0100147 int output_count() const { return output_count_; }
148
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149 Handle<JSFunction> function() const { return Handle<JSFunction>(function_); }
150 Handle<Code> compiled_code() const { return Handle<Code>(compiled_code_); }
151 BailoutType bailout_type() const { return bailout_type_; }
152
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100153 // Number of created JS frames. Not all created frames are necessarily JS.
154 int jsframe_count() const { return jsframe_count_; }
155
Ben Murdochb0fe1622011-05-05 13:52:32 +0100156 static Deoptimizer* New(JSFunction* function,
157 BailoutType type,
158 unsigned bailout_id,
159 Address from,
Steve Block44f0eee2011-05-26 01:26:41 +0100160 int fp_to_sp_delta,
161 Isolate* isolate);
162 static Deoptimizer* Grab(Isolate* isolate);
163
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000164 // The returned object with information on the optimized frame needs to be
165 // freed before another one can be generated.
166 static DeoptimizedFrameInfo* DebuggerInspectableFrame(JavaScriptFrame* frame,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100167 int jsframe_index,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000168 Isolate* isolate);
169 static void DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
170 Isolate* isolate);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000171
Steve Block44f0eee2011-05-26 01:26:41 +0100172 // Makes sure that there is enough room in the relocation
173 // information of a code object to perform lazy deoptimization
174 // patching. If there is not enough room a new relocation
175 // information object is allocated and comments are added until it
176 // is big enough.
177 static void EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100178
179 // Deoptimize the function now. Its current optimized code will never be run
180 // again and any activations of the optimized code will get deoptimized when
181 // execution returns.
182 static void DeoptimizeFunction(JSFunction* function);
183
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000184 // Deoptimize all code in the given isolate.
185 static void DeoptimizeAll(Isolate* isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100186
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000187 // Deoptimize code associated with the given global object.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100188 static void DeoptimizeGlobalObject(JSObject* object);
189
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000190 // Deoptimizes all optimized code that has been previously marked
191 // (via code->set_marked_for_deoptimization) and unlinks all functions that
192 // refer to that code.
193 static void DeoptimizeMarkedCode(Isolate* isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100194
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000195 // Visit all the known optimized functions in a given isolate.
196 static void VisitAllOptimizedFunctions(
197 Isolate* isolate, OptimizedFunctionVisitor* visitor);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100198
Steve Block1e0659c2011-05-24 12:43:12 +0100199 // The size in bytes of the code required at a lazy deopt patch site.
200 static int patch_size();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100201
Ben Murdochb0fe1622011-05-05 13:52:32 +0100202 ~Deoptimizer();
203
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000204 void MaterializeHeapObjects(JavaScriptFrameIterator* it);
205
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000206 void MaterializeHeapNumbersForDebuggerInspectableFrame(
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100207 Address parameters_top,
208 uint32_t parameters_size,
209 Address expressions_top,
210 uint32_t expressions_size,
211 DeoptimizedFrameInfo* info);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100212
Ben Murdoch8b112d22011-06-08 16:22:53 +0100213 static void ComputeOutputFrames(Deoptimizer* deoptimizer);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100214
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000215
216 enum GetEntryMode {
217 CALCULATE_ENTRY_ADDRESS,
218 ENSURE_ENTRY_CODE
219 };
220
221
222 static Address GetDeoptimizationEntry(
223 Isolate* isolate,
224 int id,
225 BailoutType type,
226 GetEntryMode mode = ENSURE_ENTRY_CODE);
227 static int GetDeoptimizationId(Isolate* isolate,
228 Address addr,
229 BailoutType type);
Steve Block9fac8402011-05-12 15:51:54 +0100230 static int GetOutputInfo(DeoptimizationOutputData* data,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000231 BailoutId node_id,
Steve Block9fac8402011-05-12 15:51:54 +0100232 SharedFunctionInfo* shared);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100233
Ben Murdochb0fe1622011-05-05 13:52:32 +0100234 // Code generation support.
235 static int input_offset() { return OFFSET_OF(Deoptimizer, input_); }
236 static int output_count_offset() {
237 return OFFSET_OF(Deoptimizer, output_count_);
238 }
239 static int output_offset() { return OFFSET_OF(Deoptimizer, output_); }
240
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000241 static int has_alignment_padding_offset() {
242 return OFFSET_OF(Deoptimizer, has_alignment_padding_);
243 }
244
Steve Block44f0eee2011-05-26 01:26:41 +0100245 static int GetDeoptimizedCodeCount(Isolate* isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100246
247 static const int kNotDeoptimizationEntry = -1;
248
249 // Generators for the deoptimization entry code.
250 class EntryGenerator BASE_EMBEDDED {
251 public:
252 EntryGenerator(MacroAssembler* masm, BailoutType type)
253 : masm_(masm), type_(type) { }
254 virtual ~EntryGenerator() { }
255
256 void Generate();
257
258 protected:
259 MacroAssembler* masm() const { return masm_; }
260 BailoutType type() const { return type_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000261 Isolate* isolate() const { return masm_->isolate(); }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100262
263 virtual void GeneratePrologue() { }
264
265 private:
266 MacroAssembler* masm_;
267 Deoptimizer::BailoutType type_;
268 };
269
270 class TableEntryGenerator : public EntryGenerator {
271 public:
272 TableEntryGenerator(MacroAssembler* masm, BailoutType type, int count)
273 : EntryGenerator(masm, type), count_(count) { }
274
275 protected:
276 virtual void GeneratePrologue();
277
278 private:
279 int count() const { return count_; }
280
281 int count_;
282 };
283
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100284 int ConvertJSFrameIndexToFrameIndex(int jsframe_index);
285
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000286 static size_t GetMaxDeoptTableSize();
287
288 static void EnsureCodeForDeoptimizationEntry(Isolate* isolate,
289 BailoutType type,
290 int max_entry_id);
291
292 Isolate* isolate() const { return isolate_; }
293
Ben Murdochb0fe1622011-05-05 13:52:32 +0100294 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000295 static const int kMinNumberOfEntries = 64;
296 static const int kMaxNumberOfEntries = 16384;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100297
Steve Block44f0eee2011-05-26 01:26:41 +0100298 Deoptimizer(Isolate* isolate,
299 JSFunction* function,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100300 BailoutType type,
301 unsigned bailout_id,
302 Address from,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000303 int fp_to_sp_delta,
304 Code* optimized_code);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000305 Code* FindOptimizedCode(JSFunction* function, Code* optimized_code);
306 void PrintFunctionName();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100307 void DeleteFrameDescriptions();
308
309 void DoComputeOutputFrames();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100310 void DoComputeJSFrame(TranslationIterator* iterator, int frame_index);
311 void DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
312 int frame_index);
313 void DoComputeConstructStubFrame(TranslationIterator* iterator,
314 int frame_index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000315 void DoComputeAccessorStubFrame(TranslationIterator* iterator,
316 int frame_index,
317 bool is_setter_stub_frame);
318 void DoComputeCompiledStubFrame(TranslationIterator* iterator,
319 int frame_index);
320
321 // Translate object, store the result into an auxiliary array
322 // (deferred_objects_tagged_values_).
323 void DoTranslateObject(TranslationIterator* iterator,
324 int object_index,
325 int field_index);
326
327 // Translate value, store the result into the given frame slot.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100328 void DoTranslateCommand(TranslationIterator* iterator,
329 int frame_index,
330 unsigned output_offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000331
332 // Translate object, do not store the result anywhere (but do update
333 // the deferred materialization array).
334 void DoTranslateObjectAndSkip(TranslationIterator* iterator);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100335
336 unsigned ComputeInputFrameSize() const;
337 unsigned ComputeFixedSize(JSFunction* function) const;
338
339 unsigned ComputeIncomingArgumentSize(JSFunction* function) const;
340 unsigned ComputeOutgoingArgumentSize() const;
341
342 Object* ComputeLiteral(int index) const;
343
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000344 void AddObjectStart(intptr_t slot_address, int argc, bool is_arguments);
345 void AddObjectDuplication(intptr_t slot, int object_index);
346 void AddObjectTaggedValue(intptr_t value);
347 void AddObjectDoubleValue(double value);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100348 void AddDoubleValue(intptr_t slot_address, double value);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100349
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000350 bool ArgumentsObjectIsAdapted(int object_index) {
351 ObjectMaterializationDescriptor desc = deferred_objects_.at(object_index);
352 int reverse_jsframe_index = jsframe_count_ - desc.jsframe_index() - 1;
353 return jsframe_has_adapted_arguments_[reverse_jsframe_index];
354 }
355
356 Handle<JSFunction> ArgumentsObjectFunction(int object_index) {
357 ObjectMaterializationDescriptor desc = deferred_objects_.at(object_index);
358 int reverse_jsframe_index = jsframe_count_ - desc.jsframe_index() - 1;
359 return jsframe_functions_[reverse_jsframe_index];
360 }
361
362 // Helper function for heap object materialization.
363 Handle<Object> MaterializeNextHeapObject();
364 Handle<Object> MaterializeNextValue();
365
Ben Murdochb0fe1622011-05-05 13:52:32 +0100366 static void GenerateDeoptimizationEntries(
367 MacroAssembler* masm, int count, BailoutType type);
368
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000369 // Marks all the code in the given context for deoptimization.
370 static void MarkAllCodeForContext(Context* native_context);
371
372 // Visit all the known optimized functions in a given context.
373 static void VisitAllOptimizedFunctionsForContext(
374 Context* context, OptimizedFunctionVisitor* visitor);
375
376 // Deoptimizes all code marked in the given context.
377 static void DeoptimizeMarkedCodeForContext(Context* native_context);
378
379 // Patch the given code so that it will deoptimize itself.
380 static void PatchCodeForDeoptimization(Isolate* isolate, Code* code);
381
382 // Searches the list of known deoptimizing code for a Code object
383 // containing the given address (which is supposedly faster than
384 // searching all code objects).
385 Code* FindDeoptimizingCode(Address addr);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100386
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000387 // Fill the input from from a JavaScript frame. This is used when
388 // the debugger needs to inspect an optimized frame. For normal
389 // deoptimizations the input frame is filled in generated code.
390 void FillInputFrame(Address tos, JavaScriptFrame* frame);
391
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000392 // Fill the given output frame's registers to contain the failure handler
393 // address and the number of parameters for a stub failure trampoline.
394 void SetPlatformCompiledStubRegisters(FrameDescription* output_frame,
395 CodeStubDescriptor* desc);
396
397 // Fill the given output frame's double registers with the original values
398 // from the input frame's double registers.
399 void CopyDoubleRegisters(FrameDescription* output_frame);
400
401 // Determines whether the input frame contains alignment padding by looking
402 // at the dynamic alignment state slot inside the frame.
403 bool HasAlignmentPadding(JSFunction* function);
404
Steve Block44f0eee2011-05-26 01:26:41 +0100405 Isolate* isolate_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100406 JSFunction* function_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000407 Code* compiled_code_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100408 unsigned bailout_id_;
409 BailoutType bailout_type_;
410 Address from_;
411 int fp_to_sp_delta_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000412 int has_alignment_padding_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100413
414 // Input frame description.
415 FrameDescription* input_;
416 // Number of output frames.
417 int output_count_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100418 // Number of output js frames.
419 int jsframe_count_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100420 // Array of output frame descriptions.
421 FrameDescription** output_;
422
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000423 // Deferred values to be materialized.
424 List<Object*> deferred_objects_tagged_values_;
425 List<HeapNumberMaterializationDescriptor<int> >
426 deferred_objects_double_values_;
427 List<ObjectMaterializationDescriptor> deferred_objects_;
428 List<HeapNumberMaterializationDescriptor<Address> > deferred_heap_numbers_;
429
430 // Key for lookup of previously materialized objects
431 Address stack_fp_;
432 Handle<FixedArray> previously_materialized_objects_;
433 int prev_materialized_count_;
434
435 // Output frame information. Only used during heap object materialization.
436 List<Handle<JSFunction> > jsframe_functions_;
437 List<bool> jsframe_has_adapted_arguments_;
438
439 // Materialized objects. Only used during heap object materialization.
440 List<Handle<Object> >* materialized_values_;
441 List<Handle<Object> >* materialized_objects_;
442 int materialization_value_index_;
443 int materialization_object_index_;
444
445#ifdef DEBUG
446 DisallowHeapAllocation* disallow_heap_allocation_;
447#endif // DEBUG
448
449 CodeTracer::Scope* trace_scope_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100450
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000451 static const int table_entry_size_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100452
453 friend class FrameDescription;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000454 friend class DeoptimizedFrameInfo;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100455};
456
457
458class FrameDescription {
459 public:
460 FrameDescription(uint32_t frame_size,
461 JSFunction* function);
462
463 void* operator new(size_t size, uint32_t frame_size) {
Steve Block44f0eee2011-05-26 01:26:41 +0100464 // Subtracts kPointerSize, as the member frame_content_ already supplies
465 // the first element of the area to store the frame.
466 return malloc(size + frame_size - kPointerSize);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100467 }
468
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000469 void operator delete(void* pointer, uint32_t frame_size) {
470 free(pointer);
471 }
472
Ben Murdochb0fe1622011-05-05 13:52:32 +0100473 void operator delete(void* description) {
474 free(description);
475 }
476
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000477 uint32_t GetFrameSize() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000478 DCHECK(static_cast<uint32_t>(frame_size_) == frame_size_);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000479 return static_cast<uint32_t>(frame_size_);
480 }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100481
482 JSFunction* GetFunction() const { return function_; }
483
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100484 unsigned GetOffsetFromSlotIndex(int slot_index);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100485
486 intptr_t GetFrameSlot(unsigned offset) {
487 return *GetFrameSlotPointer(offset);
488 }
489
490 double GetDoubleFrameSlot(unsigned offset) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100491 intptr_t* ptr = GetFrameSlotPointer(offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000492 return read_double_value(reinterpret_cast<Address>(ptr));
Ben Murdochb0fe1622011-05-05 13:52:32 +0100493 }
494
495 void SetFrameSlot(unsigned offset, intptr_t value) {
496 *GetFrameSlotPointer(offset) = value;
497 }
498
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000499 void SetCallerPc(unsigned offset, intptr_t value);
500
501 void SetCallerFp(unsigned offset, intptr_t value);
502
503 void SetCallerConstantPool(unsigned offset, intptr_t value);
504
Ben Murdochb0fe1622011-05-05 13:52:32 +0100505 intptr_t GetRegister(unsigned n) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000506#if DEBUG
507 // This convoluted DCHECK is needed to work around a gcc problem that
508 // improperly detects an array bounds overflow in optimized debug builds
509 // when using a plain DCHECK.
510 if (n >= arraysize(registers_)) {
511 DCHECK(false);
512 return 0;
513 }
514#endif
Ben Murdochb0fe1622011-05-05 13:52:32 +0100515 return registers_[n];
516 }
517
518 double GetDoubleRegister(unsigned n) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000519 DCHECK(n < arraysize(double_registers_));
Ben Murdochb0fe1622011-05-05 13:52:32 +0100520 return double_registers_[n];
521 }
522
523 void SetRegister(unsigned n, intptr_t value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000524 DCHECK(n < arraysize(registers_));
Ben Murdochb0fe1622011-05-05 13:52:32 +0100525 registers_[n] = value;
526 }
527
528 void SetDoubleRegister(unsigned n, double value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000529 DCHECK(n < arraysize(double_registers_));
Ben Murdochb0fe1622011-05-05 13:52:32 +0100530 double_registers_[n] = value;
531 }
532
533 intptr_t GetTop() const { return top_; }
534 void SetTop(intptr_t top) { top_ = top; }
535
536 intptr_t GetPc() const { return pc_; }
537 void SetPc(intptr_t pc) { pc_ = pc; }
538
539 intptr_t GetFp() const { return fp_; }
540 void SetFp(intptr_t fp) { fp_ = fp; }
541
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100542 intptr_t GetContext() const { return context_; }
543 void SetContext(intptr_t context) { context_ = context; }
544
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000545 intptr_t GetConstantPool() const { return constant_pool_; }
546 void SetConstantPool(intptr_t constant_pool) {
547 constant_pool_ = constant_pool;
548 }
549
Ben Murdochb0fe1622011-05-05 13:52:32 +0100550 Smi* GetState() const { return state_; }
551 void SetState(Smi* state) { state_ = state; }
552
553 void SetContinuation(intptr_t pc) { continuation_ = pc; }
554
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100555 StackFrame::Type GetFrameType() const { return type_; }
556 void SetFrameType(StackFrame::Type type) { type_ = type; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000557
558 // Get the incoming arguments count.
559 int ComputeParametersCount();
560
561 // Get a parameter value for an unoptimized frame.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100562 Object* GetParameter(int index);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000563
564 // Get the expression stack height for a unoptimized frame.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100565 unsigned GetExpressionCount();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000566
567 // Get the expression stack value for an unoptimized frame.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100568 Object* GetExpression(int index);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000569
Ben Murdochb0fe1622011-05-05 13:52:32 +0100570 static int registers_offset() {
571 return OFFSET_OF(FrameDescription, registers_);
572 }
573
574 static int double_registers_offset() {
575 return OFFSET_OF(FrameDescription, double_registers_);
576 }
577
578 static int frame_size_offset() {
579 return OFFSET_OF(FrameDescription, frame_size_);
580 }
581
582 static int pc_offset() {
583 return OFFSET_OF(FrameDescription, pc_);
584 }
585
586 static int state_offset() {
587 return OFFSET_OF(FrameDescription, state_);
588 }
589
590 static int continuation_offset() {
591 return OFFSET_OF(FrameDescription, continuation_);
592 }
593
594 static int frame_content_offset() {
Steve Block44f0eee2011-05-26 01:26:41 +0100595 return OFFSET_OF(FrameDescription, frame_content_);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100596 }
597
598 private:
599 static const uint32_t kZapUint32 = 0xbeeddead;
600
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000601 // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to
602 // keep the variable-size array frame_content_ of type intptr_t at
603 // the end of the structure aligned.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100604 uintptr_t frame_size_; // Number of bytes.
605 JSFunction* function_;
606 intptr_t registers_[Register::kNumRegisters];
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000607 double double_registers_[DoubleRegister::kMaxNumRegisters];
Ben Murdochb0fe1622011-05-05 13:52:32 +0100608 intptr_t top_;
609 intptr_t pc_;
610 intptr_t fp_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100611 intptr_t context_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000612 intptr_t constant_pool_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100613 StackFrame::Type type_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100614 Smi* state_;
615
616 // Continuation is the PC where the execution continues after
617 // deoptimizing.
618 intptr_t continuation_;
619
Steve Block44f0eee2011-05-26 01:26:41 +0100620 // This must be at the end of the object as the object is allocated larger
621 // than it's definition indicate to extend this array.
622 intptr_t frame_content_[1];
623
Ben Murdochb0fe1622011-05-05 13:52:32 +0100624 intptr_t* GetFrameSlotPointer(unsigned offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000625 DCHECK(offset < frame_size_);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100626 return reinterpret_cast<intptr_t*>(
627 reinterpret_cast<Address>(this) + frame_content_offset() + offset);
628 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100629
630 int ComputeFixedSize();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100631};
632
633
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000634class DeoptimizerData {
635 public:
636 explicit DeoptimizerData(MemoryAllocator* allocator);
637 ~DeoptimizerData();
638
639 void Iterate(ObjectVisitor* v);
640
641 private:
642 MemoryAllocator* allocator_;
643 int deopt_entry_code_entries_[Deoptimizer::kBailoutTypesWithCodeEntry];
644 MemoryChunk* deopt_entry_code_[Deoptimizer::kBailoutTypesWithCodeEntry];
645
646 DeoptimizedFrameInfo* deoptimized_frame_info_;
647
648 Deoptimizer* current_;
649
650 friend class Deoptimizer;
651
652 DISALLOW_COPY_AND_ASSIGN(DeoptimizerData);
653};
654
655
Ben Murdochb0fe1622011-05-05 13:52:32 +0100656class TranslationBuffer BASE_EMBEDDED {
657 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000658 explicit TranslationBuffer(Zone* zone) : contents_(256, zone) { }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100659
660 int CurrentIndex() const { return contents_.length(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000661 void Add(int32_t value, Zone* zone);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100662
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000663 Handle<ByteArray> CreateByteArray(Factory* factory);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100664
665 private:
666 ZoneList<uint8_t> contents_;
667};
668
669
670class TranslationIterator BASE_EMBEDDED {
671 public:
672 TranslationIterator(ByteArray* buffer, int index)
673 : buffer_(buffer), index_(index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000674 DCHECK(index >= 0 && index < buffer->length());
Ben Murdochb0fe1622011-05-05 13:52:32 +0100675 }
676
677 int32_t Next();
678
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000679 bool HasNext() const { return index_ < buffer_->length(); }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100680
681 void Skip(int n) {
682 for (int i = 0; i < n; i++) Next();
683 }
684
685 private:
686 ByteArray* buffer_;
687 int index_;
688};
689
690
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000691#define TRANSLATION_OPCODE_LIST(V) \
692 V(BEGIN) \
693 V(JS_FRAME) \
694 V(CONSTRUCT_STUB_FRAME) \
695 V(GETTER_STUB_FRAME) \
696 V(SETTER_STUB_FRAME) \
697 V(ARGUMENTS_ADAPTOR_FRAME) \
698 V(COMPILED_STUB_FRAME) \
699 V(DUPLICATED_OBJECT) \
700 V(ARGUMENTS_OBJECT) \
701 V(CAPTURED_OBJECT) \
702 V(REGISTER) \
703 V(INT32_REGISTER) \
704 V(UINT32_REGISTER) \
705 V(DOUBLE_REGISTER) \
706 V(STACK_SLOT) \
707 V(INT32_STACK_SLOT) \
708 V(UINT32_STACK_SLOT) \
709 V(DOUBLE_STACK_SLOT) \
710 V(LITERAL)
711
712
Ben Murdochb0fe1622011-05-05 13:52:32 +0100713class Translation BASE_EMBEDDED {
714 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000715#define DECLARE_TRANSLATION_OPCODE_ENUM(item) item,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100716 enum Opcode {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000717 TRANSLATION_OPCODE_LIST(DECLARE_TRANSLATION_OPCODE_ENUM)
718 LAST = LITERAL
Ben Murdochb0fe1622011-05-05 13:52:32 +0100719 };
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000720#undef DECLARE_TRANSLATION_OPCODE_ENUM
Ben Murdochb0fe1622011-05-05 13:52:32 +0100721
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000722 Translation(TranslationBuffer* buffer, int frame_count, int jsframe_count,
723 Zone* zone)
Ben Murdochb0fe1622011-05-05 13:52:32 +0100724 : buffer_(buffer),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000725 index_(buffer->CurrentIndex()),
726 zone_(zone) {
727 buffer_->Add(BEGIN, zone);
728 buffer_->Add(frame_count, zone);
729 buffer_->Add(jsframe_count, zone);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100730 }
731
732 int index() const { return index_; }
733
734 // Commands.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000735 void BeginJSFrame(BailoutId node_id, int literal_id, unsigned height);
736 void BeginCompiledStubFrame();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100737 void BeginArgumentsAdaptorFrame(int literal_id, unsigned height);
738 void BeginConstructStubFrame(int literal_id, unsigned height);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000739 void BeginGetterStubFrame(int literal_id);
740 void BeginSetterStubFrame(int literal_id);
741 void BeginArgumentsObject(int args_length);
742 void BeginCapturedObject(int length);
743 void DuplicateObject(int object_index);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100744 void StoreRegister(Register reg);
745 void StoreInt32Register(Register reg);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000746 void StoreUint32Register(Register reg);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100747 void StoreDoubleRegister(DoubleRegister reg);
748 void StoreStackSlot(int index);
749 void StoreInt32StackSlot(int index);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000750 void StoreUint32StackSlot(int index);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100751 void StoreDoubleStackSlot(int index);
752 void StoreLiteral(int literal_id);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000753 void StoreArgumentsObject(bool args_known, int args_index, int args_length);
754
755 Zone* zone() const { return zone_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100756
757 static int NumberOfOperandsFor(Opcode opcode);
758
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000759#if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
Ben Murdochb0fe1622011-05-05 13:52:32 +0100760 static const char* StringFor(Opcode opcode);
761#endif
762
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000763 // A literal id which refers to the JSFunction itself.
764 static const int kSelfLiteralId = -239;
765
Ben Murdochb0fe1622011-05-05 13:52:32 +0100766 private:
767 TranslationBuffer* buffer_;
768 int index_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000769 Zone* zone_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100770};
771
772
Ben Murdoch8b112d22011-06-08 16:22:53 +0100773class SlotRef BASE_EMBEDDED {
774 public:
775 enum SlotRepresentation {
776 UNKNOWN,
777 TAGGED,
778 INT32,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000779 UINT32,
Ben Murdoch8b112d22011-06-08 16:22:53 +0100780 DOUBLE,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000781 LITERAL,
782 DEFERRED_OBJECT, // Object captured by the escape analysis.
783 // The number of nested objects can be obtained
784 // with the DeferredObjectLength() method
785 // (the SlotRefs of the nested objects follow
786 // this SlotRef in the depth-first order.)
787 DUPLICATE_OBJECT, // Duplicated object of a deferred object.
788 ARGUMENTS_OBJECT // Arguments object - only used to keep indexing
789 // in sync, it should not be materialized.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100790 };
791
792 SlotRef()
793 : addr_(NULL), representation_(UNKNOWN) { }
794
795 SlotRef(Address addr, SlotRepresentation representation)
796 : addr_(addr), representation_(representation) { }
797
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000798 SlotRef(Isolate* isolate, Object* literal)
799 : literal_(literal, isolate), representation_(LITERAL) { }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100800
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000801 static SlotRef NewArgumentsObject(int length) {
802 SlotRef slot;
803 slot.representation_ = ARGUMENTS_OBJECT;
804 slot.deferred_object_length_ = length;
805 return slot;
806 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100807
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000808 static SlotRef NewDeferredObject(int length) {
809 SlotRef slot;
810 slot.representation_ = DEFERRED_OBJECT;
811 slot.deferred_object_length_ = length;
812 return slot;
813 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100814
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000815 SlotRepresentation Representation() { return representation_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100816
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000817 static SlotRef NewDuplicateObject(int id) {
818 SlotRef slot;
819 slot.representation_ = DUPLICATE_OBJECT;
820 slot.duplicate_object_id_ = id;
821 return slot;
822 }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100823
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000824 int GetChildrenCount() {
825 if (representation_ == DEFERRED_OBJECT ||
826 representation_ == ARGUMENTS_OBJECT) {
827 return deferred_object_length_;
828 } else {
829 return 0;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100830 }
831 }
832
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000833 int DuplicateObjectId() { return duplicate_object_id_; }
834
835 Handle<Object> GetValue(Isolate* isolate);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100836
837 private:
838 Address addr_;
839 Handle<Object> literal_;
840 SlotRepresentation representation_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000841 int deferred_object_length_;
842 int duplicate_object_id_;
843};
844
845class SlotRefValueBuilder BASE_EMBEDDED {
846 public:
847 SlotRefValueBuilder(
848 JavaScriptFrame* frame,
849 int inlined_frame_index,
850 int formal_parameter_count);
851
852 void Prepare(Isolate* isolate);
853 Handle<Object> GetNext(Isolate* isolate, int level);
854 void Finish(Isolate* isolate);
855
856 int args_length() { return args_length_; }
857
858 private:
859 List<Handle<Object> > materialized_objects_;
860 Handle<FixedArray> previously_materialized_objects_;
861 int prev_materialized_count_;
862 Address stack_frame_id_;
863 List<SlotRef> slot_refs_;
864 int current_slot_;
865 int args_length_;
866 int first_slot_index_;
867
868 static SlotRef ComputeSlotForNextArgument(
869 Translation::Opcode opcode,
870 TranslationIterator* iterator,
871 DeoptimizationInputData* data,
872 JavaScriptFrame* frame);
873
874 Handle<Object> GetPreviouslyMaterialized(Isolate* isolate, int length);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100875
876 static Address SlotAddress(JavaScriptFrame* frame, int slot_index) {
877 if (slot_index >= 0) {
878 const int offset = JavaScriptFrameConstants::kLocal0Offset;
879 return frame->fp() + offset - (slot_index * kPointerSize);
880 } else {
881 const int offset = JavaScriptFrameConstants::kLastParameterOffset;
882 return frame->fp() + offset - ((slot_index + 1) * kPointerSize);
883 }
884 }
885
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000886 Handle<Object> GetDeferredObject(Isolate* isolate);
887};
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100888
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000889class MaterializedObjectStore {
890 public:
891 explicit MaterializedObjectStore(Isolate* isolate) : isolate_(isolate) {
892 }
893
894 Handle<FixedArray> Get(Address fp);
895 void Set(Address fp, Handle<FixedArray> materialized_objects);
896 void Remove(Address fp);
897
898 private:
899 Isolate* isolate() { return isolate_; }
900 Handle<FixedArray> GetStackEntries();
901 Handle<FixedArray> EnsureStackEntries(int size);
902
903 int StackIdToIndex(Address fp);
904
905 Isolate* isolate_;
906 List<Address> frame_fps_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100907};
908
909
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000910// Class used to represent an unoptimized frame when the debugger
911// needs to inspect a frame that is part of an optimized frame. The
912// internally used FrameDescription objects are not GC safe so for use
913// by the debugger frame information is copied to an object of this type.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100914// Represents parameters in unadapted form so their number might mismatch
915// formal parameter count.
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000916class DeoptimizedFrameInfo : public Malloced {
917 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100918 DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
919 int frame_index,
920 bool has_arguments_adaptor,
921 bool has_construct_stub);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000922 virtual ~DeoptimizedFrameInfo();
923
924 // GC support.
925 void Iterate(ObjectVisitor* v);
926
927 // Return the number of incoming arguments.
928 int parameters_count() { return parameters_count_; }
929
930 // Return the height of the expression stack.
931 int expression_count() { return expression_count_; }
932
933 // Get the frame function.
934 JSFunction* GetFunction() {
935 return function_;
936 }
937
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000938 // Get the frame context.
939 Object* GetContext() { return context_; }
940
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100941 // Check if this frame is preceded by construct stub frame. The bottom-most
942 // inlined frame might still be called by an uninlined construct stub.
943 bool HasConstructStub() {
944 return has_construct_stub_;
945 }
946
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000947 // Get an incoming argument.
948 Object* GetParameter(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000949 DCHECK(0 <= index && index < parameters_count());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000950 return parameters_[index];
951 }
952
953 // Get an expression from the expression stack.
954 Object* GetExpression(int index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000955 DCHECK(0 <= index && index < expression_count());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000956 return expression_stack_[index];
957 }
958
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100959 int GetSourcePosition() {
960 return source_position_;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000961 }
962
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100963 private:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000964 // Set an incoming argument.
965 void SetParameter(int index, Object* obj) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000966 DCHECK(0 <= index && index < parameters_count());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000967 parameters_[index] = obj;
968 }
969
970 // Set an expression on the expression stack.
971 void SetExpression(int index, Object* obj) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000972 DCHECK(0 <= index && index < expression_count());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000973 expression_stack_[index] = obj;
974 }
975
976 JSFunction* function_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000977 Object* context_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100978 bool has_construct_stub_;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000979 int parameters_count_;
980 int expression_count_;
981 Object** parameters_;
982 Object** expression_stack_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100983 int source_position_;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000984
985 friend class Deoptimizer;
986};
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000987
Ben Murdochb0fe1622011-05-05 13:52:32 +0100988} } // namespace v8::internal
989
990#endif // V8_DEOPTIMIZER_H_