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

Side by Side Diff: src/deoptimizer.cc

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « src/deoptimizer.h ('k') | src/diy-fp.h » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
(...skipping 25 matching lines...) Expand all
37 37
38 38
39 namespace v8 { 39 namespace v8 {
40 namespace internal { 40 namespace internal {
41 41
42 DeoptimizerData::DeoptimizerData() { 42 DeoptimizerData::DeoptimizerData() {
43 eager_deoptimization_entry_code_ = NULL; 43 eager_deoptimization_entry_code_ = NULL;
44 lazy_deoptimization_entry_code_ = NULL; 44 lazy_deoptimization_entry_code_ = NULL;
45 current_ = NULL; 45 current_ = NULL;
46 deoptimizing_code_list_ = NULL; 46 deoptimizing_code_list_ = NULL;
47 #ifdef ENABLE_DEBUGGER_SUPPORT
48 deoptimized_frame_info_ = NULL;
49 #endif
47 } 50 }
48 51
49 52
50 DeoptimizerData::~DeoptimizerData() { 53 DeoptimizerData::~DeoptimizerData() {
51 if (eager_deoptimization_entry_code_ != NULL) { 54 if (eager_deoptimization_entry_code_ != NULL) {
52 Isolate::Current()->memory_allocator()->Free( 55 Isolate::Current()->memory_allocator()->Free(
53 eager_deoptimization_entry_code_); 56 eager_deoptimization_entry_code_);
54 eager_deoptimization_entry_code_ = NULL; 57 eager_deoptimization_entry_code_ = NULL;
55 } 58 }
56 if (lazy_deoptimization_entry_code_ != NULL) { 59 if (lazy_deoptimization_entry_code_ != NULL) {
57 Isolate::Current()->memory_allocator()->Free( 60 Isolate::Current()->memory_allocator()->Free(
58 lazy_deoptimization_entry_code_); 61 lazy_deoptimization_entry_code_);
59 lazy_deoptimization_entry_code_ = NULL; 62 lazy_deoptimization_entry_code_ = NULL;
60 } 63 }
61 } 64 }
62 65
66
67 #ifdef ENABLE_DEBUGGER_SUPPORT
68 void DeoptimizerData::Iterate(ObjectVisitor* v) {
69 if (deoptimized_frame_info_ != NULL) {
70 deoptimized_frame_info_->Iterate(v);
71 }
72 }
73 #endif
74
75
63 Deoptimizer* Deoptimizer::New(JSFunction* function, 76 Deoptimizer* Deoptimizer::New(JSFunction* function,
64 BailoutType type, 77 BailoutType type,
65 unsigned bailout_id, 78 unsigned bailout_id,
66 Address from, 79 Address from,
67 int fp_to_sp_delta, 80 int fp_to_sp_delta,
68 Isolate* isolate) { 81 Isolate* isolate) {
69 ASSERT(isolate == Isolate::Current()); 82 ASSERT(isolate == Isolate::Current());
70 Deoptimizer* deoptimizer = new Deoptimizer(isolate, 83 Deoptimizer* deoptimizer = new Deoptimizer(isolate,
71 function, 84 function,
72 type, 85 type,
73 bailout_id, 86 bailout_id,
74 from, 87 from,
75 fp_to_sp_delta); 88 fp_to_sp_delta,
89 NULL);
76 ASSERT(isolate->deoptimizer_data()->current_ == NULL); 90 ASSERT(isolate->deoptimizer_data()->current_ == NULL);
77 isolate->deoptimizer_data()->current_ = deoptimizer; 91 isolate->deoptimizer_data()->current_ = deoptimizer;
78 return deoptimizer; 92 return deoptimizer;
79 } 93 }
80 94
81 95
82 Deoptimizer* Deoptimizer::Grab(Isolate* isolate) { 96 Deoptimizer* Deoptimizer::Grab(Isolate* isolate) {
83 ASSERT(isolate == Isolate::Current()); 97 ASSERT(isolate == Isolate::Current());
84 Deoptimizer* result = isolate->deoptimizer_data()->current_; 98 Deoptimizer* result = isolate->deoptimizer_data()->current_;
85 ASSERT(result != NULL); 99 ASSERT(result != NULL);
86 result->DeleteFrameDescriptions(); 100 result->DeleteFrameDescriptions();
87 isolate->deoptimizer_data()->current_ = NULL; 101 isolate->deoptimizer_data()->current_ = NULL;
88 return result; 102 return result;
89 } 103 }
90 104
105 #ifdef ENABLE_DEBUGGER_SUPPORT
106 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
107 JavaScriptFrame* frame,
108 int frame_index,
109 Isolate* isolate) {
110 ASSERT(isolate == Isolate::Current());
111 ASSERT(frame->is_optimized());
112 ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == NULL);
113
114 // Get the function and code from the frame.
115 JSFunction* function = JSFunction::cast(frame->function());
116 Code* code = frame->LookupCode();
117 Address code_start_address = code->instruction_start();
118
119 // Locate the deoptimization point in the code. As we are at a call the
120 // return address must be at a place in the code with deoptimization support.
121 int deoptimization_index = Safepoint::kNoDeoptimizationIndex;
122 // Scope this as the safe point constructor will disallow allocation.
123 {
124 SafepointTable table(code);
125 for (unsigned i = 0; i < table.length(); ++i) {
126 Address address = code_start_address + table.GetPcOffset(i);
127 if (address == frame->pc()) {
128 SafepointEntry safepoint_entry = table.GetEntry(i);
129 ASSERT(safepoint_entry.deoptimization_index() !=
130 Safepoint::kNoDeoptimizationIndex);
131 deoptimization_index = safepoint_entry.deoptimization_index();
132 break;
133 }
134 }
135 }
136 ASSERT(deoptimization_index != Safepoint::kNoDeoptimizationIndex);
137
138 // Always use the actual stack slots when calculating the fp to sp
139 // delta adding two for the function and context.
140 unsigned stack_slots = code->stack_slots();
141 unsigned fp_to_sp_delta = ((stack_slots + 2) * kPointerSize);
142
143 Deoptimizer* deoptimizer = new Deoptimizer(isolate,
144 function,
145 Deoptimizer::DEBUGGER,
146 deoptimization_index,
147 frame->pc(),
148 fp_to_sp_delta,
149 code);
150 Address tos = frame->fp() - fp_to_sp_delta;
151 deoptimizer->FillInputFrame(tos, frame);
152
153 // Calculate the output frames.
154 Deoptimizer::ComputeOutputFrames(deoptimizer);
155
156 // Create the GC safe output frame information and register it for GC
157 // handling.
158 ASSERT_LT(frame_index, deoptimizer->output_count());
159 DeoptimizedFrameInfo* info =
160 new DeoptimizedFrameInfo(deoptimizer, frame_index);
161 isolate->deoptimizer_data()->deoptimized_frame_info_ = info;
162
163 // Get the "simulated" top and size for the requested frame.
164 Address top =
165 reinterpret_cast<Address>(deoptimizer->output_[frame_index]->GetTop());
166 uint32_t size = deoptimizer->output_[frame_index]->GetFrameSize();
167
168 // Done with the GC-unsafe frame descriptions. This re-enables allocation.
169 deoptimizer->DeleteFrameDescriptions();
170
171 // Allocate a heap number for the doubles belonging to this frame.
172 deoptimizer->MaterializeHeapNumbersForDebuggerInspectableFrame(
173 top, size, info);
174
175 // Finished using the deoptimizer instance.
176 delete deoptimizer;
177
178 return info;
179 }
180
181
182 void Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
183 Isolate* isolate) {
184 ASSERT(isolate == Isolate::Current());
185 ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == info);
186 delete info;
187 isolate->deoptimizer_data()->deoptimized_frame_info_ = NULL;
188 }
189 #endif
91 190
92 void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm, 191 void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
93 int count, 192 int count,
94 BailoutType type) { 193 BailoutType type) {
95 TableEntryGenerator generator(masm, type, count); 194 TableEntryGenerator generator(masm, type, count);
96 generator.Generate(); 195 generator.Generate();
97 } 196 }
98 197
99 198
100 class DeoptimizingVisitor : public OptimizedFunctionVisitor { 199 class DeoptimizingVisitor : public OptimizedFunctionVisitor {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 void Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) { 303 void Deoptimizer::ComputeOutputFrames(Deoptimizer* deoptimizer) {
205 deoptimizer->DoComputeOutputFrames(); 304 deoptimizer->DoComputeOutputFrames();
206 } 305 }
207 306
208 307
209 Deoptimizer::Deoptimizer(Isolate* isolate, 308 Deoptimizer::Deoptimizer(Isolate* isolate,
210 JSFunction* function, 309 JSFunction* function,
211 BailoutType type, 310 BailoutType type,
212 unsigned bailout_id, 311 unsigned bailout_id,
213 Address from, 312 Address from,
214 int fp_to_sp_delta) 313 int fp_to_sp_delta,
314 Code* optimized_code)
215 : isolate_(isolate), 315 : isolate_(isolate),
216 function_(function), 316 function_(function),
217 bailout_id_(bailout_id), 317 bailout_id_(bailout_id),
218 bailout_type_(type), 318 bailout_type_(type),
219 from_(from), 319 from_(from),
220 fp_to_sp_delta_(fp_to_sp_delta), 320 fp_to_sp_delta_(fp_to_sp_delta),
321 input_(NULL),
221 output_count_(0), 322 output_count_(0),
222 output_(NULL), 323 output_(NULL),
223 deferred_heap_numbers_(0) { 324 deferred_heap_numbers_(0) {
224 if (FLAG_trace_deopt && type != OSR) { 325 if (FLAG_trace_deopt && type != OSR) {
225 PrintF("**** DEOPT: "); 326 if (type == DEBUGGER) {
327 PrintF("**** DEOPT FOR DEBUGGER: ");
328 } else {
329 PrintF("**** DEOPT: ");
330 }
226 function->PrintName(); 331 function->PrintName();
227 PrintF(" at bailout #%u, address 0x%" V8PRIxPTR ", frame size %d\n", 332 PrintF(" at bailout #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
228 bailout_id, 333 bailout_id,
229 reinterpret_cast<intptr_t>(from), 334 reinterpret_cast<intptr_t>(from),
230 fp_to_sp_delta - (2 * kPointerSize)); 335 fp_to_sp_delta - (2 * kPointerSize));
231 } else if (FLAG_trace_osr && type == OSR) { 336 } else if (FLAG_trace_osr && type == OSR) {
232 PrintF("**** OSR: "); 337 PrintF("**** OSR: ");
233 function->PrintName(); 338 function->PrintName();
234 PrintF(" at ast id #%u, address 0x%" V8PRIxPTR ", frame size %d\n", 339 PrintF(" at ast id #%u, address 0x%" V8PRIxPTR ", frame size %d\n",
235 bailout_id, 340 bailout_id,
236 reinterpret_cast<intptr_t>(from), 341 reinterpret_cast<intptr_t>(from),
237 fp_to_sp_delta - (2 * kPointerSize)); 342 fp_to_sp_delta - (2 * kPointerSize));
238 } 343 }
239 // Find the optimized code. 344 // Find the optimized code.
240 if (type == EAGER) { 345 if (type == EAGER) {
241 ASSERT(from == NULL); 346 ASSERT(from == NULL);
242 optimized_code_ = function_->code(); 347 optimized_code_ = function_->code();
243 } else if (type == LAZY) { 348 } else if (type == LAZY) {
244 optimized_code_ = FindDeoptimizingCodeFromAddress(from); 349 optimized_code_ = FindDeoptimizingCodeFromAddress(from);
245 ASSERT(optimized_code_ != NULL); 350 ASSERT(optimized_code_ != NULL);
246 } else if (type == OSR) { 351 } else if (type == OSR) {
247 // The function has already been optimized and we're transitioning 352 // The function has already been optimized and we're transitioning
248 // from the unoptimized shared version to the optimized one in the 353 // from the unoptimized shared version to the optimized one in the
249 // function. The return address (from) points to unoptimized code. 354 // function. The return address (from) points to unoptimized code.
250 optimized_code_ = function_->code(); 355 optimized_code_ = function_->code();
251 ASSERT(optimized_code_->kind() == Code::OPTIMIZED_FUNCTION); 356 ASSERT(optimized_code_->kind() == Code::OPTIMIZED_FUNCTION);
252 ASSERT(!optimized_code_->contains(from)); 357 ASSERT(!optimized_code_->contains(from));
358 } else if (type == DEBUGGER) {
359 optimized_code_ = optimized_code;
360 ASSERT(optimized_code_->contains(from));
253 } 361 }
254 ASSERT(HEAP->allow_allocation(false)); 362 ASSERT(HEAP->allow_allocation(false));
255 unsigned size = ComputeInputFrameSize(); 363 unsigned size = ComputeInputFrameSize();
256 input_ = new(size) FrameDescription(size, function); 364 input_ = new(size) FrameDescription(size, function);
365 #ifdef DEBUG
366 input_->SetKind(Code::OPTIMIZED_FUNCTION);
367 #endif
257 } 368 }
258 369
259 370
260 Deoptimizer::~Deoptimizer() { 371 Deoptimizer::~Deoptimizer() {
261 ASSERT(input_ == NULL && output_ == NULL); 372 ASSERT(input_ == NULL && output_ == NULL);
262 } 373 }
263 374
264 375
265 void Deoptimizer::DeleteFrameDescriptions() { 376 void Deoptimizer::DeleteFrameDescriptions() {
266 delete input_; 377 delete input_;
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 output_[index]->GetPc(), 523 output_[index]->GetPc(),
413 FullCodeGenerator::State2String( 524 FullCodeGenerator::State2String(
414 static_cast<FullCodeGenerator::State>( 525 static_cast<FullCodeGenerator::State>(
415 output_[index]->GetState()->value())), 526 output_[index]->GetState()->value())),
416 ms); 527 ms);
417 } 528 }
418 } 529 }
419 530
420 531
421 void Deoptimizer::MaterializeHeapNumbers() { 532 void Deoptimizer::MaterializeHeapNumbers() {
533 ASSERT_NE(DEBUGGER, bailout_type_);
422 for (int i = 0; i < deferred_heap_numbers_.length(); i++) { 534 for (int i = 0; i < deferred_heap_numbers_.length(); i++) {
423 HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i]; 535 HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i];
424 Handle<Object> num = isolate_->factory()->NewNumber(d.value()); 536 Handle<Object> num = isolate_->factory()->NewNumber(d.value());
425 if (FLAG_trace_deopt) { 537 if (FLAG_trace_deopt) {
426 PrintF("Materializing a new heap number %p [%e] in slot %p\n", 538 PrintF("Materializing a new heap number %p [%e] in slot %p\n",
427 reinterpret_cast<void*>(*num), 539 reinterpret_cast<void*>(*num),
428 d.value(), 540 d.value(),
429 d.slot_address()); 541 d.slot_address());
430 } 542 }
431 543
432 Memory::Object_at(d.slot_address()) = *num; 544 Memory::Object_at(d.slot_address()) = *num;
433 } 545 }
434 } 546 }
435 547
436 548
549 #ifdef ENABLE_DEBUGGER_SUPPORT
550 void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
551 Address top, uint32_t size, DeoptimizedFrameInfo* info) {
552 ASSERT_EQ(DEBUGGER, bailout_type_);
553 for (int i = 0; i < deferred_heap_numbers_.length(); i++) {
554 HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i];
555
556 // Check of the heap number to materialize actually belong to the frame
557 // being extracted.
558 Address slot = d.slot_address();
559 if (top <= slot && slot < top + size) {
560 Handle<Object> num = isolate_->factory()->NewNumber(d.value());
561 // Calculate the index with the botton of the expression stack
562 // at index 0, and the fixed part (including incoming arguments)
563 // at negative indexes.
564 int index = static_cast<int>(
565 info->expression_count_ - (slot - top) / kPointerSize - 1);
566 if (FLAG_trace_deopt) {
567 PrintF("Materializing a new heap number %p [%e] in slot %p"
568 "for stack index %d\n",
569 reinterpret_cast<void*>(*num),
570 d.value(),
571 d.slot_address(),
572 index);
573 }
574 if (index >=0) {
575 info->SetExpression(index, *num);
576 } else {
577 // Calculate parameter index subtracting one for the receiver.
578 int parameter_index =
579 index +
580 static_cast<int>(size) / kPointerSize -
581 info->expression_count_ - 1;
582 info->SetParameter(parameter_index, *num);
583 }
584 }
585 }
586 }
587 #endif
588
589
437 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, 590 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
438 int frame_index, 591 int frame_index,
439 unsigned output_offset) { 592 unsigned output_offset) {
440 disasm::NameConverter converter; 593 disasm::NameConverter converter;
441 // A GC-safe temporary placeholder that we can put in the output frame. 594 // A GC-safe temporary placeholder that we can put in the output frame.
442 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); 595 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0));
443 596
444 // Ignore commands marked as duplicate and act on the first non-duplicate. 597 // Ignore commands marked as duplicate and act on the first non-duplicate.
445 Translation::Opcode opcode = 598 Translation::Opcode opcode =
446 static_cast<Translation::Opcode>(iterator->Next()); 599 static_cast<Translation::Opcode>(iterator->Next());
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 masm.set_emit_debug_code(false); 1055 masm.set_emit_debug_code(false);
903 GenerateDeoptimizationEntries(&masm, kNumberOfEntries, type); 1056 GenerateDeoptimizationEntries(&masm, kNumberOfEntries, type);
904 CodeDesc desc; 1057 CodeDesc desc;
905 masm.GetCode(&desc); 1058 masm.GetCode(&desc);
906 ASSERT(desc.reloc_size == 0); 1059 ASSERT(desc.reloc_size == 0);
907 1060
908 MemoryChunk* chunk = 1061 MemoryChunk* chunk =
909 Isolate::Current()->memory_allocator()->AllocateChunk(desc.instr_size, 1062 Isolate::Current()->memory_allocator()->AllocateChunk(desc.instr_size,
910 EXECUTABLE, 1063 EXECUTABLE,
911 NULL); 1064 NULL);
1065 if (chunk == NULL) {
1066 V8::FatalProcessOutOfMemory("Not enough memory for deoptimization table");
1067 }
912 memcpy(chunk->body(), desc.buffer, desc.instr_size); 1068 memcpy(chunk->body(), desc.buffer, desc.instr_size);
913 CPU::FlushICache(chunk->body(), desc.instr_size); 1069 CPU::FlushICache(chunk->body(), desc.instr_size);
914 return chunk; 1070 return chunk;
915 } 1071 }
916 1072
917 1073
918 Code* Deoptimizer::FindDeoptimizingCodeFromAddress(Address addr) { 1074 Code* Deoptimizer::FindDeoptimizingCodeFromAddress(Address addr) {
919 DeoptimizingCodeListNode* node = 1075 DeoptimizingCodeListNode* node =
920 Isolate::Current()->deoptimizer_data()->deoptimizing_code_list_; 1076 Isolate::Current()->deoptimizer_data()->deoptimizing_code_list_;
921 while (node != NULL) { 1077 while (node != NULL) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 SetFrameSlot(o, kZapUint32); 1126 SetFrameSlot(o, kZapUint32);
971 } 1127 }
972 } 1128 }
973 1129
974 1130
975 unsigned FrameDescription::GetOffsetFromSlotIndex(Deoptimizer* deoptimizer, 1131 unsigned FrameDescription::GetOffsetFromSlotIndex(Deoptimizer* deoptimizer,
976 int slot_index) { 1132 int slot_index) {
977 if (slot_index >= 0) { 1133 if (slot_index >= 0) {
978 // Local or spill slots. Skip the fixed part of the frame 1134 // Local or spill slots. Skip the fixed part of the frame
979 // including all arguments. 1135 // including all arguments.
980 unsigned base = static_cast<unsigned>( 1136 unsigned base =
981 GetFrameSize() - deoptimizer->ComputeFixedSize(GetFunction())); 1137 GetFrameSize() - deoptimizer->ComputeFixedSize(GetFunction());
982 return base - ((slot_index + 1) * kPointerSize); 1138 return base - ((slot_index + 1) * kPointerSize);
983 } else { 1139 } else {
984 // Incoming parameter. 1140 // Incoming parameter.
985 unsigned base = static_cast<unsigned>(GetFrameSize() - 1141 unsigned base = GetFrameSize() -
986 deoptimizer->ComputeIncomingArgumentSize(GetFunction())); 1142 deoptimizer->ComputeIncomingArgumentSize(GetFunction());
987 return base - ((slot_index + 1) * kPointerSize); 1143 return base - ((slot_index + 1) * kPointerSize);
988 } 1144 }
989 } 1145 }
990 1146
991 1147
1148 int FrameDescription::ComputeParametersCount() {
1149 return function_->shared()->formal_parameter_count();
1150 }
1151
1152
1153 Object* FrameDescription::GetParameter(Deoptimizer* deoptimizer, int index) {
1154 ASSERT_EQ(Code::FUNCTION, kind_);
1155 ASSERT(index >= 0);
1156 ASSERT(index < ComputeParametersCount());
1157 // The slot indexes for incoming arguments are negative.
1158 unsigned offset = GetOffsetFromSlotIndex(deoptimizer,
1159 index - ComputeParametersCount());
1160 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
1161 }
1162
1163
1164 unsigned FrameDescription::GetExpressionCount(Deoptimizer* deoptimizer) {
1165 ASSERT_EQ(Code::FUNCTION, kind_);
1166 unsigned size = GetFrameSize() - deoptimizer->ComputeFixedSize(GetFunction());
1167 return size / kPointerSize;
1168 }
1169
1170
1171 Object* FrameDescription::GetExpression(Deoptimizer* deoptimizer, int index) {
1172 ASSERT_EQ(Code::FUNCTION, kind_);
1173 unsigned offset = GetOffsetFromSlotIndex(deoptimizer, index);
1174 return reinterpret_cast<Object*>(*GetFrameSlotPointer(offset));
1175 }
1176
1177
992 void TranslationBuffer::Add(int32_t value) { 1178 void TranslationBuffer::Add(int32_t value) {
993 // Encode the sign bit in the least significant bit. 1179 // Encode the sign bit in the least significant bit.
994 bool is_negative = (value < 0); 1180 bool is_negative = (value < 0);
995 uint32_t bits = ((is_negative ? -value : value) << 1) | 1181 uint32_t bits = ((is_negative ? -value : value) << 1) |
996 static_cast<int32_t>(is_negative); 1182 static_cast<int32_t>(is_negative);
997 // Encode the individual bytes using the least significant bit of 1183 // Encode the individual bytes using the least significant bit of
998 // each byte to indicate whether or not more bytes follow. 1184 // each byte to indicate whether or not more bytes follow.
999 do { 1185 do {
1000 uint32_t next = bits >> 7; 1186 uint32_t next = bits >> 7;
1001 contents_.Add(((bits << 1) & 0xFF) | (next != 0)); 1187 contents_.Add(((bits << 1) & 0xFF) | (next != 0));
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1105 case LITERAL: 1291 case LITERAL:
1106 return 1; 1292 return 1;
1107 case FRAME: 1293 case FRAME:
1108 return 3; 1294 return 3;
1109 } 1295 }
1110 UNREACHABLE(); 1296 UNREACHABLE();
1111 return -1; 1297 return -1;
1112 } 1298 }
1113 1299
1114 1300
1115 #ifdef OBJECT_PRINT 1301 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
1116 1302
1117 const char* Translation::StringFor(Opcode opcode) { 1303 const char* Translation::StringFor(Opcode opcode) {
1118 switch (opcode) { 1304 switch (opcode) {
1119 case BEGIN: 1305 case BEGIN:
1120 return "BEGIN"; 1306 return "BEGIN";
1121 case FRAME: 1307 case FRAME:
1122 return "FRAME"; 1308 return "FRAME";
1123 case REGISTER: 1309 case REGISTER:
1124 return "REGISTER"; 1310 return "REGISTER";
1125 case INT32_REGISTER: 1311 case INT32_REGISTER:
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1254 return; 1440 return;
1255 } 1441 }
1256 frames_to_skip--; 1442 frames_to_skip--;
1257 } 1443 }
1258 } 1444 }
1259 1445
1260 UNREACHABLE(); 1446 UNREACHABLE();
1261 } 1447 }
1262 1448
1263 1449
1450 DeoptimizedFrameInfo::DeoptimizedFrameInfo(
1451 Deoptimizer* deoptimizer, int frame_index) {
1452 FrameDescription* output_frame = deoptimizer->output_[frame_index];
1453 SetFunction(output_frame->GetFunction());
1454 expression_count_ = output_frame->GetExpressionCount(deoptimizer);
1455 parameters_count_ = output_frame->ComputeParametersCount();
1456 parameters_ = new Object*[parameters_count_];
1457 for (int i = 0; i < parameters_count_; i++) {
1458 SetParameter(i, output_frame->GetParameter(deoptimizer, i));
1459 }
1460 expression_stack_ = new Object*[expression_count_];
1461 for (int i = 0; i < expression_count_; i++) {
1462 SetExpression(i, output_frame->GetExpression(deoptimizer, i));
1463 }
1464 }
1465
1466
1467 DeoptimizedFrameInfo::~DeoptimizedFrameInfo() {
1468 delete[] expression_stack_;
1469 delete[] parameters_;
1470 }
1471
1472 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) {
1473 v->VisitPointer(reinterpret_cast<Object**>(&function_));
1474 v->VisitPointers(parameters_, parameters_ + parameters_count_);
1475 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_);
1476 }
1477
1478
1264 } } // namespace v8::internal 1479 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/deoptimizer.h ('k') | src/diy-fp.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698