Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: src/deoptimizer.h

Issue 1136223004: Unify reading of deoptimization information. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_DEOPTIMIZER_H_ 5 #ifndef V8_DEOPTIMIZER_H_
6 #define V8_DEOPTIMIZER_H_ 6 #define V8_DEOPTIMIZER_H_
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/allocation.h" 10 #include "src/allocation.h"
11 #include "src/macro-assembler.h" 11 #include "src/macro-assembler.h"
12 12
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 16
17 17
18 static inline double read_double_value(Address p) { 18 static inline double read_double_value(Address p) {
19 double d; 19 double d;
20 memcpy(&d, p, sizeof(d)); 20 memcpy(&d, p, sizeof(d));
21 return d; 21 return d;
22 } 22 }
23 23
24 24
25 class FrameDescription; 25 class FrameDescription;
26 class TranslationIterator; 26 class TranslationIterator;
27 class DeoptimizedFrameInfo; 27 class DeoptimizedFrameInfo;
28 28
29 class TranslatedState;
30 class RegisterValues;
31
32 class TranslatedValue BASE_EMBEDDED {
33 public:
34 enum Kind {
35 UNKNOWN,
36 TAGGED,
37 INT32,
38 UINT32,
39 BOOLBIT,
40 DOUBLE,
41 DEFERRED_OBJECT, // Object captured by the escape analysis.
42 // The number of nested objects can be obtained
43 // with the DeferredObjectLength() method
44 // (the values of the nested objects follow
45 // this value in the depth-first order.)
46 DUPLICATE_OBJECT, // Duplicated object of a deferred object.
47 ARGUMENTS_OBJECT // Arguments object - only used to keep indexing
48 // in sync, it should not be materialized.
49 };
50
51 Kind kind() { return kind_; }
52
53 int GetChildrenCount() {
54 if (kind() == DEFERRED_OBJECT || kind() == ARGUMENTS_OBJECT) {
55 return deferred_object_length_;
56 } else {
57 return 0;
58 }
59 }
60
61 int ObjectIndex() {
62 DCHECK(DUPLICATE_OBJECT == kind() || DEFERRED_OBJECT == kind() ||
63 ARGUMENTS_OBJECT == kind());
64 return object_index_;
65 }
66
67 void Handlify();
68
69 // Allocation-less getter of the value.
70 // Returns heap()->arguments_marker() if allocation would be
71 // necessary to get the value.
72 Object* GetRawValue();
73 Handle<Object> GetValue();
74
75 bool IsMaterializedObject();
76
77 private:
78 friend class TranslatedState;
79
80 TranslatedValue(TranslatedState* container, Kind kind)
81 : kind_(kind),
82 container_(container),
83 raw_literal_(nullptr),
84 integral_value_(0),
85 double_value_(0),
86 deferred_object_length_(-1),
87 object_index_(-1) {}
88
89 static TranslatedValue NewArgumentsObject(TranslatedState* container,
90 int length, int object_index);
91 static TranslatedValue NewDeferredObject(TranslatedState* container,
92 int length, int object_index);
93 static TranslatedValue NewDuplicateObject(TranslatedState* container, int id);
94 static TranslatedValue NewDouble(TranslatedState* container, double value);
95 static TranslatedValue NewInt32(TranslatedState* container, uint32_t value);
96 static TranslatedValue NewUInt32(TranslatedState* container, uint32_t value);
97 static TranslatedValue NewBool(TranslatedState* container, uint32_t value);
98 static TranslatedValue NewTagged(TranslatedState* container, Object* literal);
99 static TranslatedValue NewInvalid();
100
101 Isolate* isolate();
102 void MaterializeSimple();
103
104 Kind kind_;
105 TranslatedState* container_; // This is only needed for materialization of
106 // objects and constructing handles (to get
107 // to the isolate).
108
109 MaybeHandle<Object> value_; // Before handlification, this is always null,
110 // after materialization it is never null,
111 // in between it is only null if the value needs
112 // to be materialized.
113
114 // The following is supposed to be a union.
Benedikt Meurer 2015/06/03 04:02:17 Why not use a union here?
Jarin 2015/06/03 09:28:07 Done.
115
116 // - kind TAGGED. After handlification it is always nullptr.
117 Object* raw_literal_;
118
119 // - kind is INT32, UINT32 or BOOLBIT.
120 uint32_t integral_value_;
121
122 // - kind is DOUBLE
123 double double_value_;
124
125 // - kind is ARGUMENTS_OBJECT or DEFERRED_OBJECT.
126 int deferred_object_length_;
127 // - kind is DUPLICATE_OBJECT or ARGUMENTS_OBJECT or DEFERRED_OBJECT.
128 int object_index_;
129 };
130
131
132 class TranslatedFrame {
133 public:
134 enum Kind {
135 Function,
Benedikt Meurer 2015/06/03 04:02:17 Add k prefix to these constants.
Jarin 2015/06/03 09:28:07 Done.
136 Getter,
137 Setter,
138 ArgumentsAdaptor,
139 ConstructStub,
140 CompiledStub,
141 Invalid
142 };
143
144 int GetValueCount();
145
146 Kind kind() const { return kind_; }
147 BailoutId node_id() { return node_id_; }
148 JSFunction* raw_function() { return raw_function_; }
149 Handle<JSFunction> function() { return function_; }
150 int height() { return height_; }
151
152 class ValueIterator {
Benedikt Meurer 2015/06/03 04:02:17 Can we have STL naming here? I.e. rename ValueIter
Jarin 2015/06/03 09:28:07 Done.
153 public:
154 ValueIterator& operator++() {
155 AdvanceIterator(&position_);
156 return *this;
157 }
158
159 ValueIterator operator++(int) {
160 ValueIterator original(position_);
161 AdvanceIterator(&position_);
162 return original;
163 }
164
165 bool operator==(const ValueIterator& other) const {
166 return position_ == other.position_;
167 }
168 bool operator!=(const ValueIterator& other) const {
169 return !(*this == other);
170 }
171
172 TranslatedValue& operator*() { return (*position_); }
173 TranslatedValue* operator->() { return &(*position_); }
174
175 private:
176 friend TranslatedFrame;
177
178 explicit ValueIterator(std::deque<TranslatedValue>::iterator position)
179 : position_(position) {}
180
181 std::deque<TranslatedValue>::iterator position_;
182 };
183
184 ValueIterator begin() { return ValueIterator(values_.begin()); }
185 ValueIterator end() { return ValueIterator(values_.end()); }
186
187 private:
188 friend class TranslatedState;
189
190 // Constructor static methods.
191 static TranslatedFrame JSFrame(BailoutId node_id, JSFunction* function,
192 int height);
193 static TranslatedFrame AccessorFrame(Kind kind, JSFunction* function);
194 static TranslatedFrame ArgumentsAdaptorFrame(JSFunction* function,
195 int height);
196 static TranslatedFrame ConstructStubFrame(JSFunction* function, int height);
197 static TranslatedFrame CompiledStubFrame(int height, Isolate* isolate) {
198 return TranslatedFrame(CompiledStub, isolate, nullptr, height);
199 }
200 static TranslatedFrame InvalidFrame() {
201 return TranslatedFrame(Invalid, nullptr);
202 }
203
204 static void AdvanceIterator(std::deque<TranslatedValue>::iterator* iter);
205
206 TranslatedFrame(Kind kind, Isolate* isolate, JSFunction* function = nullptr,
207 int height = 0)
208 : kind_(kind),
209 node_id_(BailoutId::None()),
210 raw_function_(function),
211 height_(height),
212 isolate_(isolate) {}
213
214
215 void Add(const TranslatedValue& value) { values_.push_back(value); }
216 void Handlify(Isolate* isolate);
217
218 Kind kind_;
219 BailoutId node_id_;
220 JSFunction* raw_function_;
221 Handle<JSFunction> function_;
222 int height_;
223 Isolate* isolate_;
224
225 typedef std::deque<TranslatedValue> ValuesContainer;
226
227 ValuesContainer values_;
228 };
229
230
231 // Auxiliary class for translating deoptimization values.
232 // Typical usage sequence:
233 //
234 // 1. Construct the instance. This will involve reading out the translations
235 // and resolving them to values using the supplied frame pointer and
236 // machine state (registers). This phase is guaranteed not to allocate
237 // and not to use any HandleScope. Any object pointers will be stored raw.
238 //
239 // 2. Handlify pointers. This will convert all the raw pointers to handles.
240 //
241 // 3. Reading out the frame values.
242 //
243 // Note: After the instance is constructed, it is possible to iterate over
244 // the values eagerly.
245
246 class TranslatedState {
247 public:
248 TranslatedState();
249 explicit TranslatedState(JavaScriptFrame* frame);
250
251 void Prepare(bool has_adapted_arguments, Address stack_frame_pointer);
252
253 // Store newly materialized values into the isolate.
254 void StoreMaterializedValuesAndDeopt();
255
256 std::vector<TranslatedFrame>& frames() { return frames_; }
257
258 TranslatedFrame* GetArgumentsInfoFromJSFrameIndex(int jsframe_index,
259 int* arguments_count);
260
261 Isolate* isolate() { return isolate_; }
262
263 void Init(Address input_frame_pointer, JSFunction* input_frame_function,
264 TranslationIterator* iterator, FixedArray* literal_array,
265 RegisterValues* registers, FILE* trace_file);
266
267 private:
268 friend TranslatedValue;
269
270 TranslatedFrame CreateNextTranslatedFrame(TranslationIterator* iterator,
271 FixedArray* literal_array,
272 Address fp,
273 JSFunction* frame_function,
274 FILE* trace_file);
275 TranslatedValue CreateNextTranslatedValue(int frame_index, int value_index,
276 TranslationIterator* iterator,
277 FixedArray* literal_array,
278 Address fp,
279 RegisterValues* registers,
280 FILE* trace_file);
281
282 void UpdateFromPreviouslyMaterializedObjects();
283 Handle<Object> MaterializeAt(int frame_index, int* value_index);
284 Handle<Object> MaterializeObjectAt(int object_index);
285 bool GetAdaptedArguments(Handle<JSObject>* result, int frame_index);
286
287 static int SlotOffsetFp(int slot_index);
288 static Address SlotAddress(Address fp, int slot_index);
289 static uint32_t GetUInt32Slot(Address fp, int slot_index);
290
291 std::vector<TranslatedFrame> frames_;
292 Isolate* isolate_;
293 Address stack_frame_pointer_;
294 bool has_adapted_arguments_;
295
296 struct ObjectPosition {
297 int frame_index_;
298 int value_index_;
299 };
300 std::deque<ObjectPosition> object_positions_;
301 };
302
29 template<typename T> 303 template<typename T>
30 class HeapNumberMaterializationDescriptor BASE_EMBEDDED { 304 class HeapNumberMaterializationDescriptor BASE_EMBEDDED {
31 public: 305 public:
32 HeapNumberMaterializationDescriptor(T destination, double value) 306 HeapNumberMaterializationDescriptor(T destination, double value)
33 : destination_(destination), value_(value) { } 307 : destination_(destination), value_(value) { }
34 308
35 T destination() const { return destination_; } 309 T destination() const { return destination_; }
36 double value() const { return value_; } 310 double value() const { return value_; }
37 311
38 private: 312 private:
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 Isolate* isolate, OptimizedFunctionVisitor* visitor); 547 Isolate* isolate, OptimizedFunctionVisitor* visitor);
274 548
275 // The size in bytes of the code required at a lazy deopt patch site. 549 // The size in bytes of the code required at a lazy deopt patch site.
276 static int patch_size(); 550 static int patch_size();
277 551
278 ~Deoptimizer(); 552 ~Deoptimizer();
279 553
280 void MaterializeHeapObjects(JavaScriptFrameIterator* it); 554 void MaterializeHeapObjects(JavaScriptFrameIterator* it);
281 555
282 void MaterializeHeapNumbersForDebuggerInspectableFrame( 556 void MaterializeHeapNumbersForDebuggerInspectableFrame(
283 Address parameters_top, 557 int frame_index, int parameter_count, int expression_count,
284 uint32_t parameters_size,
285 Address expressions_top,
286 uint32_t expressions_size,
287 DeoptimizedFrameInfo* info); 558 DeoptimizedFrameInfo* info);
288 559
289 static void ComputeOutputFrames(Deoptimizer* deoptimizer); 560 static void ComputeOutputFrames(Deoptimizer* deoptimizer);
290 561
291 562
292 enum GetEntryMode { 563 enum GetEntryMode {
293 CALCULATE_ENTRY_ADDRESS, 564 CALCULATE_ENTRY_ADDRESS,
294 ENSURE_ENTRY_CODE 565 ENSURE_ENTRY_CODE
295 }; 566 };
296 567
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 void DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, 646 void DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
376 int frame_index); 647 int frame_index);
377 void DoComputeConstructStubFrame(TranslationIterator* iterator, 648 void DoComputeConstructStubFrame(TranslationIterator* iterator,
378 int frame_index); 649 int frame_index);
379 void DoComputeAccessorStubFrame(TranslationIterator* iterator, 650 void DoComputeAccessorStubFrame(TranslationIterator* iterator,
380 int frame_index, 651 int frame_index,
381 bool is_setter_stub_frame); 652 bool is_setter_stub_frame);
382 void DoComputeCompiledStubFrame(TranslationIterator* iterator, 653 void DoComputeCompiledStubFrame(TranslationIterator* iterator,
383 int frame_index); 654 int frame_index);
384 655
385 // Translate object, store the result into an auxiliary array 656 void WriteValueToOutput(TranslatedFrame::ValueIterator* iterator,
386 // (deferred_objects_tagged_values_). 657 int* input_index, int frame_index,
387 void DoTranslateObject(TranslationIterator* iterator, 658 unsigned output_offset,
388 int object_index, 659 Address output_address_for_materialization = nullptr);
389 int field_index);
390
391 // Translate value, store the result into the given frame slot.
392 void DoTranslateCommand(TranslationIterator* iterator,
393 int frame_index,
394 unsigned output_offset);
395
396 // Translate object, do not store the result anywhere (but do update
397 // the deferred materialization array).
398 void DoTranslateObjectAndSkip(TranslationIterator* iterator);
399 660
400 unsigned ComputeInputFrameSize() const; 661 unsigned ComputeInputFrameSize() const;
401 unsigned ComputeFixedSize(JSFunction* function) const; 662 unsigned ComputeFixedSize(JSFunction* function) const;
402 663
403 unsigned ComputeIncomingArgumentSize(JSFunction* function) const; 664 unsigned ComputeIncomingArgumentSize(JSFunction* function) const;
404 unsigned ComputeOutgoingArgumentSize() const; 665 unsigned ComputeOutgoingArgumentSize() const;
405 666
406 Object* ComputeLiteral(int index) const; 667 Object* ComputeLiteral(int index) const;
407 668
408 void AddObjectStart(intptr_t slot_address, int argc, bool is_arguments);
409 void AddObjectDuplication(intptr_t slot, int object_index);
410 void AddObjectTaggedValue(intptr_t value);
411 void AddObjectDoubleValue(double value);
412 void AddDoubleValue(intptr_t slot_address, double value);
413
414 bool ArgumentsObjectIsAdapted(int object_index) {
415 ObjectMaterializationDescriptor desc = deferred_objects_.at(object_index);
416 int reverse_jsframe_index = jsframe_count_ - desc.jsframe_index() - 1;
417 return jsframe_has_adapted_arguments_[reverse_jsframe_index];
418 }
419
420 Handle<JSFunction> ArgumentsObjectFunction(int object_index) {
421 ObjectMaterializationDescriptor desc = deferred_objects_.at(object_index);
422 int reverse_jsframe_index = jsframe_count_ - desc.jsframe_index() - 1;
423 return jsframe_functions_[reverse_jsframe_index];
424 }
425
426 // Helper function for heap object materialization.
427 Handle<Object> MaterializeNextHeapObject();
428 Handle<Object> MaterializeNextValue();
429
430 static void GenerateDeoptimizationEntries( 669 static void GenerateDeoptimizationEntries(
431 MacroAssembler* masm, int count, BailoutType type); 670 MacroAssembler* masm, int count, BailoutType type);
432 671
433 // Marks all the code in the given context for deoptimization. 672 // Marks all the code in the given context for deoptimization.
434 static void MarkAllCodeForContext(Context* native_context); 673 static void MarkAllCodeForContext(Context* native_context);
435 674
436 // Visit all the known optimized functions in a given context. 675 // Visit all the known optimized functions in a given context.
437 static void VisitAllOptimizedFunctionsForContext( 676 static void VisitAllOptimizedFunctionsForContext(
438 Context* context, OptimizedFunctionVisitor* visitor); 677 Context* context, OptimizedFunctionVisitor* visitor);
439 678
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 716
478 // Input frame description. 717 // Input frame description.
479 FrameDescription* input_; 718 FrameDescription* input_;
480 // Number of output frames. 719 // Number of output frames.
481 int output_count_; 720 int output_count_;
482 // Number of output js frames. 721 // Number of output js frames.
483 int jsframe_count_; 722 int jsframe_count_;
484 // Array of output frame descriptions. 723 // Array of output frame descriptions.
485 FrameDescription** output_; 724 FrameDescription** output_;
486 725
487 // Deferred values to be materialized.
488 List<Object*> deferred_objects_tagged_values_;
489 List<HeapNumberMaterializationDescriptor<int> >
490 deferred_objects_double_values_;
491 List<ObjectMaterializationDescriptor> deferred_objects_;
492 List<HeapNumberMaterializationDescriptor<Address> > deferred_heap_numbers_;
493
494 // Key for lookup of previously materialized objects 726 // Key for lookup of previously materialized objects
495 Address stack_fp_; 727 Address stack_fp_;
496 Handle<FixedArray> previously_materialized_objects_; 728 Handle<FixedArray> previously_materialized_objects_;
497 int prev_materialized_count_; 729 int prev_materialized_count_;
498 730
499 // Output frame information. Only used during heap object materialization. 731 // Output frame information. Only used during heap object materialization.
500 List<Handle<JSFunction> > jsframe_functions_; 732 List<Handle<JSFunction> > jsframe_functions_;
501 List<bool> jsframe_has_adapted_arguments_; 733 List<bool> jsframe_has_adapted_arguments_;
502 734
503 // Materialized objects. Only used during heap object materialization. 735 TranslatedState translated_state_;
504 List<Handle<Object> >* materialized_values_; 736 struct ValueToMaterialize {
505 List<Handle<Object> >* materialized_objects_; 737 Address output_slot_address_;
506 int materialization_value_index_; 738 TranslatedFrame::ValueIterator value_;
507 int materialization_object_index_; 739 };
740 std::vector<ValueToMaterialize> values_to_materialize_;
508 741
509 #ifdef DEBUG 742 #ifdef DEBUG
510 DisallowHeapAllocation* disallow_heap_allocation_; 743 DisallowHeapAllocation* disallow_heap_allocation_;
511 #endif // DEBUG 744 #endif // DEBUG
512 745
513 CodeTracer::Scope* trace_scope_; 746 CodeTracer::Scope* trace_scope_;
514 747
515 static const int table_entry_size_; 748 static const int table_entry_size_;
516 749
517 friend class FrameDescription; 750 friend class FrameDescription;
518 friend class DeoptimizedFrameInfo; 751 friend class DeoptimizedFrameInfo;
519 }; 752 };
520 753
521 754
755 class RegisterValues {
756 public:
757 intptr_t GetRegister(unsigned n) const {
758 #if DEBUG
759 // This convoluted DCHECK is needed to work around a gcc problem that
760 // improperly detects an array bounds overflow in optimized debug builds
761 // when using a plain DCHECK.
762 if (n >= arraysize(registers_)) {
763 DCHECK(false);
764 return 0;
765 }
766 #endif
767 return registers_[n];
768 }
769
770 double GetDoubleRegister(unsigned n) const {
771 DCHECK(n < arraysize(double_registers_));
772 return double_registers_[n];
773 }
774
775 void SetRegister(unsigned n, intptr_t value) {
776 DCHECK(n < arraysize(registers_));
777 registers_[n] = value;
778 }
779
780 void SetDoubleRegister(unsigned n, double value) {
781 DCHECK(n < arraysize(double_registers_));
782 double_registers_[n] = value;
783 }
784
785 intptr_t registers_[Register::kNumRegisters];
Benedikt Meurer 2015/06/03 04:02:17 Nit: these should be private.
Jarin 2015/06/03 09:28:07 The offset of the field is exposed to the platform
786 double double_registers_[DoubleRegister::kMaxNumRegisters];
787 };
788
789
522 class FrameDescription { 790 class FrameDescription {
523 public: 791 public:
524 FrameDescription(uint32_t frame_size, 792 FrameDescription(uint32_t frame_size,
525 JSFunction* function); 793 JSFunction* function);
526 794
527 void* operator new(size_t size, uint32_t frame_size) { 795 void* operator new(size_t size, uint32_t frame_size) {
528 // Subtracts kPointerSize, as the member frame_content_ already supplies 796 // Subtracts kPointerSize, as the member frame_content_ already supplies
529 // the first element of the area to store the frame. 797 // the first element of the area to store the frame.
530 return malloc(size + frame_size - kPointerSize); 798 return malloc(size + frame_size - kPointerSize);
531 } 799 }
(...skipping 20 matching lines...) Expand all
552 820
553 intptr_t GetFrameSlot(unsigned offset) { 821 intptr_t GetFrameSlot(unsigned offset) {
554 return *GetFrameSlotPointer(offset); 822 return *GetFrameSlotPointer(offset);
555 } 823 }
556 824
557 double GetDoubleFrameSlot(unsigned offset) { 825 double GetDoubleFrameSlot(unsigned offset) {
558 intptr_t* ptr = GetFrameSlotPointer(offset); 826 intptr_t* ptr = GetFrameSlotPointer(offset);
559 return read_double_value(reinterpret_cast<Address>(ptr)); 827 return read_double_value(reinterpret_cast<Address>(ptr));
560 } 828 }
561 829
830 Address GetFramePointerAddress() {
831 int fp_offset = GetFrameSize() -
832 (ComputeParametersCount() + 1) * kPointerSize -
833 StandardFrameConstants::kCallerSPOffset;
834 return reinterpret_cast<Address>(GetFrameSlotPointer(fp_offset));
835 }
836
837 RegisterValues* GetRegisterValues() { return &register_values_; }
838
562 void SetFrameSlot(unsigned offset, intptr_t value) { 839 void SetFrameSlot(unsigned offset, intptr_t value) {
563 *GetFrameSlotPointer(offset) = value; 840 *GetFrameSlotPointer(offset) = value;
564 } 841 }
565 842
566 void SetCallerPc(unsigned offset, intptr_t value); 843 void SetCallerPc(unsigned offset, intptr_t value);
567 844
568 void SetCallerFp(unsigned offset, intptr_t value); 845 void SetCallerFp(unsigned offset, intptr_t value);
569 846
570 void SetCallerConstantPool(unsigned offset, intptr_t value); 847 void SetCallerConstantPool(unsigned offset, intptr_t value);
571 848
572 intptr_t GetRegister(unsigned n) const { 849 intptr_t GetRegister(unsigned n) const {
573 #if DEBUG 850 return register_values_.GetRegister(n);
574 // This convoluted DCHECK is needed to work around a gcc problem that
575 // improperly detects an array bounds overflow in optimized debug builds
576 // when using a plain DCHECK.
577 if (n >= arraysize(registers_)) {
578 DCHECK(false);
579 return 0;
580 }
581 #endif
582 return registers_[n];
583 } 851 }
584 852
585 double GetDoubleRegister(unsigned n) const { 853 double GetDoubleRegister(unsigned n) const {
586 DCHECK(n < arraysize(double_registers_)); 854 return register_values_.GetDoubleRegister(n);
587 return double_registers_[n];
588 } 855 }
589 856
590 void SetRegister(unsigned n, intptr_t value) { 857 void SetRegister(unsigned n, intptr_t value) {
591 DCHECK(n < arraysize(registers_)); 858 register_values_.SetRegister(n, value);
592 registers_[n] = value;
593 } 859 }
594 860
595 void SetDoubleRegister(unsigned n, double value) { 861 void SetDoubleRegister(unsigned n, double value) {
596 DCHECK(n < arraysize(double_registers_)); 862 register_values_.SetDoubleRegister(n, value);
597 double_registers_[n] = value;
598 } 863 }
599 864
600 intptr_t GetTop() const { return top_; } 865 intptr_t GetTop() const { return top_; }
601 void SetTop(intptr_t top) { top_ = top; } 866 void SetTop(intptr_t top) { top_ = top; }
602 867
603 intptr_t GetPc() const { return pc_; } 868 intptr_t GetPc() const { return pc_; }
604 void SetPc(intptr_t pc) { pc_ = pc; } 869 void SetPc(intptr_t pc) { pc_ = pc; }
605 870
606 intptr_t GetFp() const { return fp_; } 871 intptr_t GetFp() const { return fp_; }
607 void SetFp(intptr_t fp) { fp_ = fp; } 872 void SetFp(intptr_t fp) { fp_ = fp; }
(...skipping 20 matching lines...) Expand all
628 // Get a parameter value for an unoptimized frame. 893 // Get a parameter value for an unoptimized frame.
629 Object* GetParameter(int index); 894 Object* GetParameter(int index);
630 895
631 // Get the expression stack height for a unoptimized frame. 896 // Get the expression stack height for a unoptimized frame.
632 unsigned GetExpressionCount(); 897 unsigned GetExpressionCount();
633 898
634 // Get the expression stack value for an unoptimized frame. 899 // Get the expression stack value for an unoptimized frame.
635 Object* GetExpression(int index); 900 Object* GetExpression(int index);
636 901
637 static int registers_offset() { 902 static int registers_offset() {
638 return OFFSET_OF(FrameDescription, registers_); 903 return OFFSET_OF(FrameDescription, register_values_.registers_);
639 } 904 }
640 905
641 static int double_registers_offset() { 906 static int double_registers_offset() {
642 return OFFSET_OF(FrameDescription, double_registers_); 907 return OFFSET_OF(FrameDescription, register_values_.double_registers_);
643 } 908 }
644 909
645 static int frame_size_offset() { 910 static int frame_size_offset() {
646 return OFFSET_OF(FrameDescription, frame_size_); 911 return OFFSET_OF(FrameDescription, frame_size_);
647 } 912 }
648 913
649 static int pc_offset() { 914 static int pc_offset() {
650 return OFFSET_OF(FrameDescription, pc_); 915 return OFFSET_OF(FrameDescription, pc_);
651 } 916 }
652 917
(...skipping 10 matching lines...) Expand all
663 } 928 }
664 929
665 private: 930 private:
666 static const uint32_t kZapUint32 = 0xbeeddead; 931 static const uint32_t kZapUint32 = 0xbeeddead;
667 932
668 // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to 933 // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to
669 // keep the variable-size array frame_content_ of type intptr_t at 934 // keep the variable-size array frame_content_ of type intptr_t at
670 // the end of the structure aligned. 935 // the end of the structure aligned.
671 uintptr_t frame_size_; // Number of bytes. 936 uintptr_t frame_size_; // Number of bytes.
672 JSFunction* function_; 937 JSFunction* function_;
673 intptr_t registers_[Register::kNumRegisters]; 938 RegisterValues register_values_;
674 double double_registers_[DoubleRegister::kMaxNumRegisters];
675 intptr_t top_; 939 intptr_t top_;
676 intptr_t pc_; 940 intptr_t pc_;
677 intptr_t fp_; 941 intptr_t fp_;
678 intptr_t context_; 942 intptr_t context_;
679 intptr_t constant_pool_; 943 intptr_t constant_pool_;
680 StackFrame::Type type_; 944 StackFrame::Type type_;
681 Smi* state_; 945 Smi* state_;
682 946
683 // Continuation is the PC where the execution continues after 947 // Continuation is the PC where the execution continues after
684 // deoptimizing. 948 // deoptimizing.
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 zone_(zone) { 1059 zone_(zone) {
796 buffer_->Add(BEGIN, zone); 1060 buffer_->Add(BEGIN, zone);
797 buffer_->Add(frame_count, zone); 1061 buffer_->Add(frame_count, zone);
798 buffer_->Add(jsframe_count, zone); 1062 buffer_->Add(jsframe_count, zone);
799 } 1063 }
800 1064
801 int index() const { return index_; } 1065 int index() const { return index_; }
802 1066
803 // Commands. 1067 // Commands.
804 void BeginJSFrame(BailoutId node_id, int literal_id, unsigned height); 1068 void BeginJSFrame(BailoutId node_id, int literal_id, unsigned height);
805 void BeginCompiledStubFrame(); 1069 void BeginCompiledStubFrame(int height);
806 void BeginArgumentsAdaptorFrame(int literal_id, unsigned height); 1070 void BeginArgumentsAdaptorFrame(int literal_id, unsigned height);
807 void BeginConstructStubFrame(int literal_id, unsigned height); 1071 void BeginConstructStubFrame(int literal_id, unsigned height);
808 void BeginGetterStubFrame(int literal_id); 1072 void BeginGetterStubFrame(int literal_id);
809 void BeginSetterStubFrame(int literal_id); 1073 void BeginSetterStubFrame(int literal_id);
810 void BeginArgumentsObject(int args_length); 1074 void BeginArgumentsObject(int args_length);
811 void BeginCapturedObject(int length); 1075 void BeginCapturedObject(int length);
812 void DuplicateObject(int object_index); 1076 void DuplicateObject(int object_index);
813 void StoreRegister(Register reg); 1077 void StoreRegister(Register reg);
814 void StoreInt32Register(Register reg); 1078 void StoreInt32Register(Register reg);
815 void StoreUint32Register(Register reg); 1079 void StoreUint32Register(Register reg);
(...skipping 18 matching lines...) Expand all
834 // A literal id which refers to the JSFunction itself. 1098 // A literal id which refers to the JSFunction itself.
835 static const int kSelfLiteralId = -239; 1099 static const int kSelfLiteralId = -239;
836 1100
837 private: 1101 private:
838 TranslationBuffer* buffer_; 1102 TranslationBuffer* buffer_;
839 int index_; 1103 int index_;
840 Zone* zone_; 1104 Zone* zone_;
841 }; 1105 };
842 1106
843 1107
844 class SlotRef BASE_EMBEDDED {
845 public:
846 enum SlotRepresentation {
847 UNKNOWN,
848 TAGGED,
849 INT32,
850 UINT32,
851 BOOLBIT,
852 DOUBLE,
853 LITERAL,
854 DEFERRED_OBJECT, // Object captured by the escape analysis.
855 // The number of nested objects can be obtained
856 // with the DeferredObjectLength() method
857 // (the SlotRefs of the nested objects follow
858 // this SlotRef in the depth-first order.)
859 DUPLICATE_OBJECT, // Duplicated object of a deferred object.
860 ARGUMENTS_OBJECT // Arguments object - only used to keep indexing
861 // in sync, it should not be materialized.
862 };
863
864 SlotRef()
865 : addr_(NULL), representation_(UNKNOWN) { }
866
867 SlotRef(Address addr, SlotRepresentation representation)
868 : addr_(addr), representation_(representation) { }
869
870 SlotRef(Isolate* isolate, Object* literal)
871 : literal_(literal, isolate), representation_(LITERAL) { }
872
873 static SlotRef NewArgumentsObject(int length) {
874 SlotRef slot;
875 slot.representation_ = ARGUMENTS_OBJECT;
876 slot.deferred_object_length_ = length;
877 return slot;
878 }
879
880 static SlotRef NewDeferredObject(int length) {
881 SlotRef slot;
882 slot.representation_ = DEFERRED_OBJECT;
883 slot.deferred_object_length_ = length;
884 return slot;
885 }
886
887 SlotRepresentation Representation() { return representation_; }
888
889 static SlotRef NewDuplicateObject(int id) {
890 SlotRef slot;
891 slot.representation_ = DUPLICATE_OBJECT;
892 slot.duplicate_object_id_ = id;
893 return slot;
894 }
895
896 int GetChildrenCount() {
897 if (representation_ == DEFERRED_OBJECT ||
898 representation_ == ARGUMENTS_OBJECT) {
899 return deferred_object_length_;
900 } else {
901 return 0;
902 }
903 }
904
905 int DuplicateObjectId() { return duplicate_object_id_; }
906
907 Handle<Object> GetValue(Isolate* isolate);
908
909 private:
910 Address addr_;
911 Handle<Object> literal_;
912 SlotRepresentation representation_;
913 int deferred_object_length_;
914 int duplicate_object_id_;
915 };
916
917 class SlotRefValueBuilder BASE_EMBEDDED {
918 public:
919 SlotRefValueBuilder(
920 JavaScriptFrame* frame,
921 int inlined_frame_index,
922 int formal_parameter_count);
923
924 void Prepare(Isolate* isolate);
925 Handle<Object> GetNext(Isolate* isolate, int level);
926 void Finish(Isolate* isolate);
927
928 int args_length() { return args_length_; }
929
930 private:
931 List<Handle<Object> > materialized_objects_;
932 Handle<FixedArray> previously_materialized_objects_;
933 int prev_materialized_count_;
934 Address stack_frame_id_;
935 List<SlotRef> slot_refs_;
936 int current_slot_;
937 int args_length_;
938 int first_slot_index_;
939 bool should_deoptimize_;
940
941 static SlotRef ComputeSlotForNextArgument(
942 Translation::Opcode opcode,
943 TranslationIterator* iterator,
944 DeoptimizationInputData* data,
945 JavaScriptFrame* frame);
946
947 Handle<Object> GetPreviouslyMaterialized(Isolate* isolate, int length);
948
949 static Address SlotAddress(JavaScriptFrame* frame, int slot_index) {
950 if (slot_index >= 0) {
951 const int offset = JavaScriptFrameConstants::kLocal0Offset;
952 return frame->fp() + offset - (slot_index * kPointerSize);
953 } else {
954 const int offset = JavaScriptFrameConstants::kLastParameterOffset;
955 return frame->fp() + offset - ((slot_index + 1) * kPointerSize);
956 }
957 }
958
959 Handle<Object> GetDeferredObject(Isolate* isolate);
960 };
961
962 class MaterializedObjectStore { 1108 class MaterializedObjectStore {
963 public: 1109 public:
964 explicit MaterializedObjectStore(Isolate* isolate) : isolate_(isolate) { 1110 explicit MaterializedObjectStore(Isolate* isolate) : isolate_(isolate) {
965 } 1111 }
966 1112
967 Handle<FixedArray> Get(Address fp); 1113 Handle<FixedArray> Get(Address fp);
968 void Set(Address fp, Handle<FixedArray> materialized_objects); 1114 void Set(Address fp, Handle<FixedArray> materialized_objects);
969 bool Remove(Address fp); 1115 bool Remove(Address fp);
970 1116
971 private: 1117 private:
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 bool has_construct_stub_; 1197 bool has_construct_stub_;
1052 int parameters_count_; 1198 int parameters_count_;
1053 int expression_count_; 1199 int expression_count_;
1054 Object** parameters_; 1200 Object** parameters_;
1055 Object** expression_stack_; 1201 Object** expression_stack_;
1056 int source_position_; 1202 int source_position_;
1057 1203
1058 friend class Deoptimizer; 1204 friend class Deoptimizer;
1059 }; 1205 };
1060 1206
1061 } } // namespace v8::internal 1207
Benedikt Meurer 2015/06/03 04:02:17 Nit: redundant empty line.
Jarin 2015/06/03 09:28:07 Done.
1208 } // namespace internal
1209 } // namespace v8
1062 1210
1063 #endif // V8_DEOPTIMIZER_H_ 1211 #endif // V8_DEOPTIMIZER_H_
OLDNEW
« no previous file with comments | « src/arm64/lithium-codegen-arm64.cc ('k') | src/deoptimizer.cc » ('j') | src/deoptimizer.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698