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

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: Fix too restrictive check 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
« no previous file with comments | « src/arm64/lithium-codegen-arm64.cc ('k') | src/deoptimizer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
18 static inline double read_double_value(Address p) {
19 double d;
20 memcpy(&d, p, sizeof(d));
21 return d;
22 }
23
24
25 class FrameDescription; 17 class FrameDescription;
26 class TranslationIterator; 18 class TranslationIterator;
27 class DeoptimizedFrameInfo; 19 class DeoptimizedFrameInfo;
20 class TranslatedState;
21 class RegisterValues;
22
23 class TranslatedValue BASE_EMBEDDED {
24 public:
25 // Allocation-less getter of the value.
26 // Returns heap()->arguments_marker() if allocation would be
27 // necessary to get the value.
28 Object* GetRawValue() const;
29 Handle<Object> GetValue();
30
31 bool IsMaterializedObject() const;
32
33 private:
34 friend class TranslatedState;
35 friend class TranslatedFrame;
36
37 enum Kind {
38 kInvalid,
39 kTagged,
40 kInt32,
41 kUInt32,
42 kBoolBit,
43 kDouble,
44 kCapturedObject, // Object captured by the escape analysis.
45 // The number of nested objects can be obtained
46 // with the DeferredObjectLength() method
47 // (the values of the nested objects follow
48 // this value in the depth-first order.)
49 kDuplicatedObject, // Duplicated object of a deferred object.
50 kArgumentsObject // Arguments object - only used to keep indexing
51 // in sync, it should not be materialized.
52 };
53
54 TranslatedValue(TranslatedState* container, Kind kind)
55 : kind_(kind), container_(container) {}
56 Kind kind() const { return kind_; }
57 void Handlify();
58 int GetChildrenCount() const;
59
60 static TranslatedValue NewArgumentsObject(TranslatedState* container,
61 int length, int object_index);
62 static TranslatedValue NewDeferredObject(TranslatedState* container,
63 int length, int object_index);
64 static TranslatedValue NewDuplicateObject(TranslatedState* container, int id);
65 static TranslatedValue NewDouble(TranslatedState* container, double value);
66 static TranslatedValue NewInt32(TranslatedState* container, int32_t value);
67 static TranslatedValue NewUInt32(TranslatedState* container, uint32_t value);
68 static TranslatedValue NewBool(TranslatedState* container, uint32_t value);
69 static TranslatedValue NewTagged(TranslatedState* container, Object* literal);
70 static TranslatedValue NewInvalid();
71
72 Isolate* isolate() const;
73 void MaterializeSimple();
74
75 Kind kind_;
76 TranslatedState* container_; // This is only needed for materialization of
77 // objects and constructing handles (to get
78 // to the isolate).
79
80 MaybeHandle<Object> value_; // Before handlification, this is always null,
81 // after materialization it is never null,
82 // in between it is only null if the value needs
83 // to be materialized.
84
85 struct MaterializedObjectInfo {
86 int id_;
87 int length_; // Applies only to kArgumentsObject or kCapturedObject kinds.
88 };
89
90 union {
91 // kind kTagged. After handlification it is always nullptr.
92 Object* raw_literal_;
93 // kind is kUInt32 or kBoolBit.
94 uint32_t uint32_value_;
95 // kind is kInt32.
96 int32_t int32_value_;
97 // kind is kDouble
98 double double_value_;
99 // kind is kDuplicatedObject or kArgumentsObject or kCapturedObject.
100 MaterializedObjectInfo materialization_info_;
101 };
102
103 // Checked accessors for the union members.
104 Object* raw_literal() const;
105 int32_t int32_value() const;
106 uint32_t uint32_value() const;
107 double double_value() const;
108 int object_length() const;
109 int object_index() const;
110 };
111
112
113 class TranslatedFrame {
114 public:
115 enum Kind {
116 kFunction,
117 kGetter,
118 kSetter,
119 kArgumentsAdaptor,
120 kConstructStub,
121 kCompiledStub,
122 kInvalid
123 };
124
125 int GetValueCount();
126
127 Kind kind() const { return kind_; }
128 BailoutId node_id() { return node_id_; }
129 JSFunction* raw_function() { return raw_function_; }
130 Handle<JSFunction> function() { return function_; }
131 int height() { return height_; }
132
133 class iterator {
134 public:
135 iterator& operator++() {
136 AdvanceIterator(&position_);
137 return *this;
138 }
139
140 iterator operator++(int) {
141 iterator original(position_);
142 AdvanceIterator(&position_);
143 return original;
144 }
145
146 bool operator==(const iterator& other) const {
147 return position_ == other.position_;
148 }
149 bool operator!=(const iterator& other) const { return !(*this == other); }
150
151 TranslatedValue& operator*() { return (*position_); }
152 TranslatedValue* operator->() { return &(*position_); }
153
154 private:
155 friend TranslatedFrame;
156
157 explicit iterator(std::deque<TranslatedValue>::iterator position)
158 : position_(position) {}
159
160 std::deque<TranslatedValue>::iterator position_;
161 };
162
163 iterator begin() { return iterator(values_.begin()); }
164 iterator end() { return iterator(values_.end()); }
165
166 private:
167 friend class TranslatedState;
168
169 // Constructor static methods.
170 static TranslatedFrame JSFrame(BailoutId node_id, JSFunction* function,
171 int height);
172 static TranslatedFrame AccessorFrame(Kind kind, JSFunction* function);
173 static TranslatedFrame ArgumentsAdaptorFrame(JSFunction* function,
174 int height);
175 static TranslatedFrame ConstructStubFrame(JSFunction* function, int height);
176 static TranslatedFrame CompiledStubFrame(int height, Isolate* isolate) {
177 return TranslatedFrame(kCompiledStub, isolate, nullptr, height);
178 }
179 static TranslatedFrame InvalidFrame() {
180 return TranslatedFrame(kInvalid, nullptr);
181 }
182
183 static void AdvanceIterator(std::deque<TranslatedValue>::iterator* iter);
184
185 TranslatedFrame(Kind kind, Isolate* isolate, JSFunction* function = nullptr,
186 int height = 0)
187 : kind_(kind),
188 node_id_(BailoutId::None()),
189 raw_function_(function),
190 height_(height),
191 isolate_(isolate) {}
192
193
194 void Add(const TranslatedValue& value) { values_.push_back(value); }
195 void Handlify(Isolate* isolate);
196
197 Kind kind_;
198 BailoutId node_id_;
199 JSFunction* raw_function_;
200 Handle<JSFunction> function_;
201 int height_;
202 Isolate* isolate_;
203
204 typedef std::deque<TranslatedValue> ValuesContainer;
205
206 ValuesContainer values_;
207 };
208
209
210 // Auxiliary class for translating deoptimization values.
211 // Typical usage sequence:
212 //
213 // 1. Construct the instance. This will involve reading out the translations
214 // and resolving them to values using the supplied frame pointer and
215 // machine state (registers). This phase is guaranteed not to allocate
216 // and not to use any HandleScope. Any object pointers will be stored raw.
217 //
218 // 2. Handlify pointers. This will convert all the raw pointers to handles.
219 //
220 // 3. Reading out the frame values.
221 //
222 // Note: After the instance is constructed, it is possible to iterate over
223 // the values eagerly.
224
225 class TranslatedState {
226 public:
227 TranslatedState();
228 explicit TranslatedState(JavaScriptFrame* frame);
229
230 void Prepare(bool has_adapted_arguments, Address stack_frame_pointer);
231
232 // Store newly materialized values into the isolate.
233 void StoreMaterializedValuesAndDeopt();
234
235 std::vector<TranslatedFrame>& frames() { return frames_; }
236
237 TranslatedFrame* GetArgumentsInfoFromJSFrameIndex(int jsframe_index,
238 int* arguments_count);
239
240 Isolate* isolate() { return isolate_; }
241
242 void Init(Address input_frame_pointer, JSFunction* input_frame_function,
243 TranslationIterator* iterator, FixedArray* literal_array,
244 RegisterValues* registers, FILE* trace_file);
245
246 private:
247 friend TranslatedValue;
248
249 TranslatedFrame CreateNextTranslatedFrame(TranslationIterator* iterator,
250 FixedArray* literal_array,
251 Address fp,
252 JSFunction* frame_function,
253 FILE* trace_file);
254 TranslatedValue CreateNextTranslatedValue(int frame_index, int value_index,
255 TranslationIterator* iterator,
256 FixedArray* literal_array,
257 Address fp,
258 RegisterValues* registers,
259 FILE* trace_file);
260
261 void UpdateFromPreviouslyMaterializedObjects();
262 Handle<Object> MaterializeAt(int frame_index, int* value_index);
263 Handle<Object> MaterializeObjectAt(int object_index);
264 bool GetAdaptedArguments(Handle<JSObject>* result, int frame_index);
265
266 static int SlotOffsetFp(int slot_index);
267 static Address SlotAddress(Address fp, int slot_index);
268 static uint32_t GetUInt32Slot(Address fp, int slot_index);
269
270 std::vector<TranslatedFrame> frames_;
271 Isolate* isolate_;
272 Address stack_frame_pointer_;
273 bool has_adapted_arguments_;
274
275 struct ObjectPosition {
276 int frame_index_;
277 int value_index_;
278 };
279 std::deque<ObjectPosition> object_positions_;
280 };
28 281
29 template<typename T> 282 template<typename T>
30 class HeapNumberMaterializationDescriptor BASE_EMBEDDED { 283 class HeapNumberMaterializationDescriptor BASE_EMBEDDED {
31 public: 284 public:
32 HeapNumberMaterializationDescriptor(T destination, double value) 285 HeapNumberMaterializationDescriptor(T destination, double value)
33 : destination_(destination), value_(value) { } 286 : destination_(destination), value_(value) { }
34 287
35 T destination() const { return destination_; } 288 T destination() const { return destination_; }
36 double value() const { return value_; } 289 double value() const { return value_; }
37 290
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 Isolate* isolate, OptimizedFunctionVisitor* visitor); 526 Isolate* isolate, OptimizedFunctionVisitor* visitor);
274 527
275 // The size in bytes of the code required at a lazy deopt patch site. 528 // The size in bytes of the code required at a lazy deopt patch site.
276 static int patch_size(); 529 static int patch_size();
277 530
278 ~Deoptimizer(); 531 ~Deoptimizer();
279 532
280 void MaterializeHeapObjects(JavaScriptFrameIterator* it); 533 void MaterializeHeapObjects(JavaScriptFrameIterator* it);
281 534
282 void MaterializeHeapNumbersForDebuggerInspectableFrame( 535 void MaterializeHeapNumbersForDebuggerInspectableFrame(
283 Address parameters_top, 536 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); 537 DeoptimizedFrameInfo* info);
288 538
289 static void ComputeOutputFrames(Deoptimizer* deoptimizer); 539 static void ComputeOutputFrames(Deoptimizer* deoptimizer);
290 540
291 541
292 enum GetEntryMode { 542 enum GetEntryMode {
293 CALCULATE_ENTRY_ADDRESS, 543 CALCULATE_ENTRY_ADDRESS,
294 ENSURE_ENTRY_CODE 544 ENSURE_ENTRY_CODE
295 }; 545 };
296 546
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 void DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator, 625 void DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
376 int frame_index); 626 int frame_index);
377 void DoComputeConstructStubFrame(TranslationIterator* iterator, 627 void DoComputeConstructStubFrame(TranslationIterator* iterator,
378 int frame_index); 628 int frame_index);
379 void DoComputeAccessorStubFrame(TranslationIterator* iterator, 629 void DoComputeAccessorStubFrame(TranslationIterator* iterator,
380 int frame_index, 630 int frame_index,
381 bool is_setter_stub_frame); 631 bool is_setter_stub_frame);
382 void DoComputeCompiledStubFrame(TranslationIterator* iterator, 632 void DoComputeCompiledStubFrame(TranslationIterator* iterator,
383 int frame_index); 633 int frame_index);
384 634
385 // Translate object, store the result into an auxiliary array 635 void WriteValueToOutput(TranslatedFrame::iterator* iterator, int* input_index,
386 // (deferred_objects_tagged_values_). 636 int frame_index, unsigned output_offset,
387 void DoTranslateObject(TranslationIterator* iterator, 637 Address output_address_for_materialization = nullptr);
388 int object_index,
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 638
400 unsigned ComputeInputFrameSize() const; 639 unsigned ComputeInputFrameSize() const;
401 unsigned ComputeFixedSize(JSFunction* function) const; 640 unsigned ComputeFixedSize(JSFunction* function) const;
402 641
403 unsigned ComputeIncomingArgumentSize(JSFunction* function) const; 642 unsigned ComputeIncomingArgumentSize(JSFunction* function) const;
404 unsigned ComputeOutgoingArgumentSize() const; 643 unsigned ComputeOutgoingArgumentSize() const;
405 644
406 Object* ComputeLiteral(int index) const; 645 Object* ComputeLiteral(int index) const;
407 646
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( 647 static void GenerateDeoptimizationEntries(
431 MacroAssembler* masm, int count, BailoutType type); 648 MacroAssembler* masm, int count, BailoutType type);
432 649
433 // Marks all the code in the given context for deoptimization. 650 // Marks all the code in the given context for deoptimization.
434 static void MarkAllCodeForContext(Context* native_context); 651 static void MarkAllCodeForContext(Context* native_context);
435 652
436 // Visit all the known optimized functions in a given context. 653 // Visit all the known optimized functions in a given context.
437 static void VisitAllOptimizedFunctionsForContext( 654 static void VisitAllOptimizedFunctionsForContext(
438 Context* context, OptimizedFunctionVisitor* visitor); 655 Context* context, OptimizedFunctionVisitor* visitor);
439 656
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 694
478 // Input frame description. 695 // Input frame description.
479 FrameDescription* input_; 696 FrameDescription* input_;
480 // Number of output frames. 697 // Number of output frames.
481 int output_count_; 698 int output_count_;
482 // Number of output js frames. 699 // Number of output js frames.
483 int jsframe_count_; 700 int jsframe_count_;
484 // Array of output frame descriptions. 701 // Array of output frame descriptions.
485 FrameDescription** output_; 702 FrameDescription** output_;
486 703
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 704 // Key for lookup of previously materialized objects
495 Address stack_fp_; 705 Address stack_fp_;
496 Handle<FixedArray> previously_materialized_objects_;
497 int prev_materialized_count_;
498 706
499 // Output frame information. Only used during heap object materialization. 707 TranslatedState translated_state_;
500 List<Handle<JSFunction> > jsframe_functions_; 708 struct ValueToMaterialize {
501 List<bool> jsframe_has_adapted_arguments_; 709 Address output_slot_address_;
502 710 TranslatedFrame::iterator value_;
503 // Materialized objects. Only used during heap object materialization. 711 };
504 List<Handle<Object> >* materialized_values_; 712 std::vector<ValueToMaterialize> values_to_materialize_;
505 List<Handle<Object> >* materialized_objects_;
506 int materialization_value_index_;
507 int materialization_object_index_;
508 713
509 #ifdef DEBUG 714 #ifdef DEBUG
510 DisallowHeapAllocation* disallow_heap_allocation_; 715 DisallowHeapAllocation* disallow_heap_allocation_;
511 #endif // DEBUG 716 #endif // DEBUG
512 717
513 CodeTracer::Scope* trace_scope_; 718 CodeTracer::Scope* trace_scope_;
514 719
515 static const int table_entry_size_; 720 static const int table_entry_size_;
516 721
517 friend class FrameDescription; 722 friend class FrameDescription;
518 friend class DeoptimizedFrameInfo; 723 friend class DeoptimizedFrameInfo;
519 }; 724 };
520 725
521 726
727 class RegisterValues {
728 public:
729 intptr_t GetRegister(unsigned n) const {
730 #if DEBUG
731 // This convoluted DCHECK is needed to work around a gcc problem that
732 // improperly detects an array bounds overflow in optimized debug builds
733 // when using a plain DCHECK.
734 if (n >= arraysize(registers_)) {
735 DCHECK(false);
736 return 0;
737 }
738 #endif
739 return registers_[n];
740 }
741
742 double GetDoubleRegister(unsigned n) const {
743 DCHECK(n < arraysize(double_registers_));
744 return double_registers_[n];
745 }
746
747 void SetRegister(unsigned n, intptr_t value) {
748 DCHECK(n < arraysize(registers_));
749 registers_[n] = value;
750 }
751
752 void SetDoubleRegister(unsigned n, double value) {
753 DCHECK(n < arraysize(double_registers_));
754 double_registers_[n] = value;
755 }
756
757 intptr_t registers_[Register::kNumRegisters];
758 double double_registers_[DoubleRegister::kMaxNumRegisters];
759 };
760
761
522 class FrameDescription { 762 class FrameDescription {
523 public: 763 public:
524 FrameDescription(uint32_t frame_size, 764 FrameDescription(uint32_t frame_size,
525 JSFunction* function); 765 JSFunction* function);
526 766
527 void* operator new(size_t size, uint32_t frame_size) { 767 void* operator new(size_t size, uint32_t frame_size) {
528 // Subtracts kPointerSize, as the member frame_content_ already supplies 768 // Subtracts kPointerSize, as the member frame_content_ already supplies
529 // the first element of the area to store the frame. 769 // the first element of the area to store the frame.
530 return malloc(size + frame_size - kPointerSize); 770 return malloc(size + frame_size - kPointerSize);
531 } 771 }
(...skipping 15 matching lines...) Expand all
547 } 787 }
548 788
549 JSFunction* GetFunction() const { return function_; } 789 JSFunction* GetFunction() const { return function_; }
550 790
551 unsigned GetOffsetFromSlotIndex(int slot_index); 791 unsigned GetOffsetFromSlotIndex(int slot_index);
552 792
553 intptr_t GetFrameSlot(unsigned offset) { 793 intptr_t GetFrameSlot(unsigned offset) {
554 return *GetFrameSlotPointer(offset); 794 return *GetFrameSlotPointer(offset);
555 } 795 }
556 796
557 double GetDoubleFrameSlot(unsigned offset) { 797 Address GetFramePointerAddress() {
558 intptr_t* ptr = GetFrameSlotPointer(offset); 798 int fp_offset = GetFrameSize() -
559 return read_double_value(reinterpret_cast<Address>(ptr)); 799 (ComputeParametersCount() + 1) * kPointerSize -
800 StandardFrameConstants::kCallerSPOffset;
801 return reinterpret_cast<Address>(GetFrameSlotPointer(fp_offset));
560 } 802 }
561 803
804 RegisterValues* GetRegisterValues() { return &register_values_; }
805
562 void SetFrameSlot(unsigned offset, intptr_t value) { 806 void SetFrameSlot(unsigned offset, intptr_t value) {
563 *GetFrameSlotPointer(offset) = value; 807 *GetFrameSlotPointer(offset) = value;
564 } 808 }
565 809
566 void SetCallerPc(unsigned offset, intptr_t value); 810 void SetCallerPc(unsigned offset, intptr_t value);
567 811
568 void SetCallerFp(unsigned offset, intptr_t value); 812 void SetCallerFp(unsigned offset, intptr_t value);
569 813
570 void SetCallerConstantPool(unsigned offset, intptr_t value); 814 void SetCallerConstantPool(unsigned offset, intptr_t value);
571 815
572 intptr_t GetRegister(unsigned n) const { 816 intptr_t GetRegister(unsigned n) const {
573 #if DEBUG 817 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 } 818 }
584 819
585 double GetDoubleRegister(unsigned n) const { 820 double GetDoubleRegister(unsigned n) const {
586 DCHECK(n < arraysize(double_registers_)); 821 return register_values_.GetDoubleRegister(n);
587 return double_registers_[n];
588 } 822 }
589 823
590 void SetRegister(unsigned n, intptr_t value) { 824 void SetRegister(unsigned n, intptr_t value) {
591 DCHECK(n < arraysize(registers_)); 825 register_values_.SetRegister(n, value);
592 registers_[n] = value;
593 } 826 }
594 827
595 void SetDoubleRegister(unsigned n, double value) { 828 void SetDoubleRegister(unsigned n, double value) {
596 DCHECK(n < arraysize(double_registers_)); 829 register_values_.SetDoubleRegister(n, value);
597 double_registers_[n] = value;
598 } 830 }
599 831
600 intptr_t GetTop() const { return top_; } 832 intptr_t GetTop() const { return top_; }
601 void SetTop(intptr_t top) { top_ = top; } 833 void SetTop(intptr_t top) { top_ = top; }
602 834
603 intptr_t GetPc() const { return pc_; } 835 intptr_t GetPc() const { return pc_; }
604 void SetPc(intptr_t pc) { pc_ = pc; } 836 void SetPc(intptr_t pc) { pc_ = pc; }
605 837
606 intptr_t GetFp() const { return fp_; } 838 intptr_t GetFp() const { return fp_; }
607 void SetFp(intptr_t fp) { fp_ = fp; } 839 void SetFp(intptr_t fp) { fp_ = fp; }
(...skipping 20 matching lines...) Expand all
628 // Get a parameter value for an unoptimized frame. 860 // Get a parameter value for an unoptimized frame.
629 Object* GetParameter(int index); 861 Object* GetParameter(int index);
630 862
631 // Get the expression stack height for a unoptimized frame. 863 // Get the expression stack height for a unoptimized frame.
632 unsigned GetExpressionCount(); 864 unsigned GetExpressionCount();
633 865
634 // Get the expression stack value for an unoptimized frame. 866 // Get the expression stack value for an unoptimized frame.
635 Object* GetExpression(int index); 867 Object* GetExpression(int index);
636 868
637 static int registers_offset() { 869 static int registers_offset() {
638 return OFFSET_OF(FrameDescription, registers_); 870 return OFFSET_OF(FrameDescription, register_values_.registers_);
639 } 871 }
640 872
641 static int double_registers_offset() { 873 static int double_registers_offset() {
642 return OFFSET_OF(FrameDescription, double_registers_); 874 return OFFSET_OF(FrameDescription, register_values_.double_registers_);
643 } 875 }
644 876
645 static int frame_size_offset() { 877 static int frame_size_offset() {
646 return OFFSET_OF(FrameDescription, frame_size_); 878 return OFFSET_OF(FrameDescription, frame_size_);
647 } 879 }
648 880
649 static int pc_offset() { 881 static int pc_offset() {
650 return OFFSET_OF(FrameDescription, pc_); 882 return OFFSET_OF(FrameDescription, pc_);
651 } 883 }
652 884
(...skipping 10 matching lines...) Expand all
663 } 895 }
664 896
665 private: 897 private:
666 static const uint32_t kZapUint32 = 0xbeeddead; 898 static const uint32_t kZapUint32 = 0xbeeddead;
667 899
668 // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to 900 // 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 901 // keep the variable-size array frame_content_ of type intptr_t at
670 // the end of the structure aligned. 902 // the end of the structure aligned.
671 uintptr_t frame_size_; // Number of bytes. 903 uintptr_t frame_size_; // Number of bytes.
672 JSFunction* function_; 904 JSFunction* function_;
673 intptr_t registers_[Register::kNumRegisters]; 905 RegisterValues register_values_;
674 double double_registers_[DoubleRegister::kMaxNumRegisters];
675 intptr_t top_; 906 intptr_t top_;
676 intptr_t pc_; 907 intptr_t pc_;
677 intptr_t fp_; 908 intptr_t fp_;
678 intptr_t context_; 909 intptr_t context_;
679 intptr_t constant_pool_; 910 intptr_t constant_pool_;
680 StackFrame::Type type_; 911 StackFrame::Type type_;
681 Smi* state_; 912 Smi* state_;
682 913
683 // Continuation is the PC where the execution continues after 914 // Continuation is the PC where the execution continues after
684 // deoptimizing. 915 // deoptimizing.
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 zone_(zone) { 1026 zone_(zone) {
796 buffer_->Add(BEGIN, zone); 1027 buffer_->Add(BEGIN, zone);
797 buffer_->Add(frame_count, zone); 1028 buffer_->Add(frame_count, zone);
798 buffer_->Add(jsframe_count, zone); 1029 buffer_->Add(jsframe_count, zone);
799 } 1030 }
800 1031
801 int index() const { return index_; } 1032 int index() const { return index_; }
802 1033
803 // Commands. 1034 // Commands.
804 void BeginJSFrame(BailoutId node_id, int literal_id, unsigned height); 1035 void BeginJSFrame(BailoutId node_id, int literal_id, unsigned height);
805 void BeginCompiledStubFrame(); 1036 void BeginCompiledStubFrame(int height);
806 void BeginArgumentsAdaptorFrame(int literal_id, unsigned height); 1037 void BeginArgumentsAdaptorFrame(int literal_id, unsigned height);
807 void BeginConstructStubFrame(int literal_id, unsigned height); 1038 void BeginConstructStubFrame(int literal_id, unsigned height);
808 void BeginGetterStubFrame(int literal_id); 1039 void BeginGetterStubFrame(int literal_id);
809 void BeginSetterStubFrame(int literal_id); 1040 void BeginSetterStubFrame(int literal_id);
810 void BeginArgumentsObject(int args_length); 1041 void BeginArgumentsObject(int args_length);
811 void BeginCapturedObject(int length); 1042 void BeginCapturedObject(int length);
812 void DuplicateObject(int object_index); 1043 void DuplicateObject(int object_index);
813 void StoreRegister(Register reg); 1044 void StoreRegister(Register reg);
814 void StoreInt32Register(Register reg); 1045 void StoreInt32Register(Register reg);
815 void StoreUint32Register(Register reg); 1046 void StoreUint32Register(Register reg);
(...skipping 18 matching lines...) Expand all
834 // A literal id which refers to the JSFunction itself. 1065 // A literal id which refers to the JSFunction itself.
835 static const int kSelfLiteralId = -239; 1066 static const int kSelfLiteralId = -239;
836 1067
837 private: 1068 private:
838 TranslationBuffer* buffer_; 1069 TranslationBuffer* buffer_;
839 int index_; 1070 int index_;
840 Zone* zone_; 1071 Zone* zone_;
841 }; 1072 };
842 1073
843 1074
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 { 1075 class MaterializedObjectStore {
963 public: 1076 public:
964 explicit MaterializedObjectStore(Isolate* isolate) : isolate_(isolate) { 1077 explicit MaterializedObjectStore(Isolate* isolate) : isolate_(isolate) {
965 } 1078 }
966 1079
967 Handle<FixedArray> Get(Address fp); 1080 Handle<FixedArray> Get(Address fp);
968 void Set(Address fp, Handle<FixedArray> materialized_objects); 1081 void Set(Address fp, Handle<FixedArray> materialized_objects);
969 bool Remove(Address fp); 1082 bool Remove(Address fp);
970 1083
971 private: 1084 private:
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 bool has_construct_stub_; 1164 bool has_construct_stub_;
1052 int parameters_count_; 1165 int parameters_count_;
1053 int expression_count_; 1166 int expression_count_;
1054 Object** parameters_; 1167 Object** parameters_;
1055 Object** expression_stack_; 1168 Object** expression_stack_;
1056 int source_position_; 1169 int source_position_;
1057 1170
1058 friend class Deoptimizer; 1171 friend class Deoptimizer;
1059 }; 1172 };
1060 1173
1061 } } // namespace v8::internal 1174 } // namespace internal
1175 } // namespace v8
1062 1176
1063 #endif // V8_DEOPTIMIZER_H_ 1177 #endif // V8_DEOPTIMIZER_H_
OLDNEW
« no previous file with comments | « src/arm64/lithium-codegen-arm64.cc ('k') | src/deoptimizer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698