43 static MemoryChunk* AllocateCodeChunk(MemoryAllocator* allocator) {
46 #
if defined(__native_client__)
58 : allocator_(allocator),
59 #ifdef ENABLE_DEBUGGER_SUPPORT
60 deoptimized_frame_info_(
NULL),
64 deopt_entry_code_entries_[i] = -1;
65 deopt_entry_code_[i] = AllocateCodeChunk(allocator);
72 allocator_->
Free(deopt_entry_code_[i]);
73 deopt_entry_code_[i] =
NULL;
78 #ifdef ENABLE_DEBUGGER_SUPPORT
79 void DeoptimizerData::Iterate(ObjectVisitor* v) {
80 if (deoptimized_frame_info_ !=
NULL) {
81 deoptimized_frame_info_->Iterate(v);
87 Code* Deoptimizer::FindDeoptimizingCode(
Address addr) {
88 if (function_->IsHeapObject()) {
91 Object* element = native_context->DeoptimizedCodeListHead();
92 while (!element->IsUndefined()) {
94 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
95 if (code->contains(addr))
return code;
96 element = code->next_code_link();
125 static const int kDeoptTableMaxEpilogueCodeSize = 2 *
KB;
130 Deoptimizer::kMaxNumberOfEntries * Deoptimizer::table_entry_size_;
132 int page_count = ((kDeoptTableMaxEpilogueCodeSize + entries_size - 1) /
133 commit_page_size) + 1;
134 return static_cast<size_t>(commit_page_size * page_count);
141 result->DeleteFrameDescriptions();
148 if (jsframe_index == 0)
return 0;
151 while (jsframe_index >= 0) {
159 return frame_index - 1;
163 #ifdef ENABLE_DEBUGGER_SUPPORT
164 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
168 ASSERT(frame->is_optimized());
173 Code* code = frame->LookupCode();
178 int deoptimization_index = safepoint_entry.deoptimization_index();
179 ASSERT(deoptimization_index != Safepoint::kNoDeoptimizationIndex);
184 unsigned fp_to_sp_delta = (stack_slots *
kPointerSize) +
190 deoptimization_index,
194 Address tos = frame->fp() - fp_to_sp_delta;
195 deoptimizer->FillInputFrame(tos, frame);
207 bool has_arguments_adaptor =
209 deoptimizer->output_[frame_index - 1]->
GetFrameType() ==
212 int construct_offset = has_arguments_adaptor ? 2 : 1;
213 bool has_construct_stub =
214 frame_index >= construct_offset &&
215 deoptimizer->output_[frame_index - construct_offset]->
GetFrameType() ==
216 StackFrame::CONSTRUCT;
220 has_arguments_adaptor,
226 deoptimizer->output_[
227 has_arguments_adaptor ? (frame_index - 1) : frame_index];
229 uint32_t parameters_size = (info->parameters_count() + 1) *
kPointerSize;
234 uint32_t expressions_size = info->expression_count() *
kPointerSize;
236 deoptimizer->output_[frame_index]->
GetTop());
239 deoptimizer->DeleteFrameDescriptions();
242 deoptimizer->MaterializeHeapNumbersForDebuggerInspectableFrame(
243 parameters_top, parameters_size, expressions_top, expressions_size, info);
252 void Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
254 ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ ==
info);
256 isolate->deoptimizer_data()->deoptimized_frame_info_ =
NULL;
260 void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
263 TableEntryGenerator generator(masm, type, count);
264 generator.Generate();
268 void Deoptimizer::VisitAllOptimizedFunctionsForContext(
269 Context* context, OptimizedFunctionVisitor* visitor) {
272 ASSERT(context->IsNativeContext());
274 visitor->EnterContext(context);
278 JSFunction* prev =
NULL;
279 Object* element = context->OptimizedFunctionsListHead();
280 while (!element->IsUndefined()) {
282 Object* next =
function->next_function_link();
283 if (
function->code()->kind() != Code::OPTIMIZED_FUNCTION ||
284 (visitor->VisitFunction(
function),
285 function->code()->kind() != Code::OPTIMIZED_FUNCTION)) {
290 prev->set_next_function_link(next);
292 context->SetOptimizedFunctionsListHead(next);
298 function->set_next_function_link(context->GetHeap()->undefined_value());
308 visitor->LeaveContext(context);
314 OptimizedFunctionVisitor* visitor) {
319 while (!context->IsUndefined()) {
320 VisitAllOptimizedFunctionsForContext(
Context::cast(context), visitor);
329 void Deoptimizer::DeoptimizeMarkedCodeForContext(
Context* context) {
334 class SelectedCodeUnlinker:
public OptimizedFunctionVisitor {
336 virtual void EnterContext(
Context* context) { }
337 virtual void LeaveContext(
Context* context) { }
338 virtual void VisitFunction(JSFunction*
function) {
339 Code* code =
function->code();
340 if (!code->marked_for_deoptimization())
return;
343 SharedFunctionInfo* shared =
function->shared();
344 function->set_code(shared->code());
346 if (FLAG_trace_deopt) {
347 CodeTracer::Scope scope(code->GetHeap()->isolate()->GetCodeTracer());
348 PrintF(scope.file(),
"[deoptimizer unlinked: ");
349 function->PrintName(scope.file());
351 " / %" V8PRIxPTR "]\n",
reinterpret_cast<intptr_t
>(
function));
357 SelectedCodeUnlinker unlinker;
358 VisitAllOptimizedFunctionsForContext(context, &unlinker);
362 Code* topmost_optimized_code =
NULL;
363 bool safe_to_deopt_topmost_optimized_code =
false;
367 for (StackFrameIterator it(isolate, isolate->thread_local_top());
368 !it.done(); it.Advance()) {
370 if (type == StackFrame::OPTIMIZED) {
371 Code* code = it.frame()->LookupCode();
372 if (FLAG_trace_deopt) {
373 JSFunction*
function =
374 static_cast<OptimizedFrame*
>(it.frame())->
function();
375 CodeTracer::Scope scope(isolate->GetCodeTracer());
376 PrintF(scope.file(),
"[deoptimizer found activation of function: ");
377 function->PrintName(scope.file());
379 " / %" V8PRIxPTR "]\n",
reinterpret_cast<intptr_t
>(
function));
381 SafepointEntry safepoint = code->GetSafepointEntry(it.frame()->pc());
382 int deopt_index = safepoint.deoptimization_index();
383 bool safe_to_deopt = deopt_index != Safepoint::kNoDeoptimizationIndex;
384 CHECK(topmost_optimized_code ==
NULL || safe_to_deopt);
385 if (topmost_optimized_code ==
NULL) {
386 topmost_optimized_code =
code;
387 safe_to_deopt_topmost_optimized_code = safe_to_deopt;
396 ZoneList<Code*> codes(10, &zone);
401 while (!element->IsUndefined()) {
403 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
404 Object* next = code->next_code_link();
405 if (code->marked_for_deoptimization()) {
407 codes.Add(code, &zone);
411 prev->set_next_code_link(next);
429 HandleScope scope(isolate);
432 for (
int i = 0; i < codes.length(); i++) {
434 if (codes[i] == topmost_optimized_code) {
435 ASSERT(safe_to_deopt_topmost_optimized_code);
440 PatchCodeForDeoptimization(isolate, codes[i]);
445 isolate->heap()->mark_compact_collector()->InvalidateCode(codes[i]);
451 if (FLAG_trace_deopt) {
453 PrintF(scope.file(),
"[deoptimize all code in all contexts]\n");
458 while (!context->IsUndefined()) {
460 MarkAllCodeForContext(native_context);
461 DeoptimizeMarkedCodeForContext(native_context);
468 if (FLAG_trace_deopt) {
470 PrintF(scope.file(),
"[deoptimize marked code in all contexts]\n");
475 while (!context->IsUndefined()) {
477 DeoptimizeMarkedCodeForContext(native_context);
484 if (FLAG_trace_deopt) {
486 PrintF(scope.file(),
"[deoptimize global object @ 0x%08" V8PRIxPTR "]\n",
487 reinterpret_cast<intptr_t
>(object));
489 if (object->IsJSGlobalProxy()) {
491 ASSERT(proto->IsJSGlobalObject());
493 MarkAllCodeForContext(native_context);
494 DeoptimizeMarkedCodeForContext(native_context);
495 }
else if (object->IsGlobalObject()) {
497 MarkAllCodeForContext(native_context);
498 DeoptimizeMarkedCodeForContext(native_context);
503 void Deoptimizer::MarkAllCodeForContext(
Context* context) {
505 while (!element->IsUndefined()) {
507 ASSERT(code->
kind() == Code::OPTIMIZED_FUNCTION);
509 element = code->next_code_link();
515 Code* code =
function->code();
516 if (code->
kind() == Code::OPTIMIZED_FUNCTION) {
521 DeoptimizeMarkedCodeForContext(
function->context()->native_context());
527 deoptimizer->DoComputeOutputFrames();
533 switch (deopt_type) {
539 ? FLAG_trace_stub_failures
549 case EAGER:
return "eager";
550 case SOFT:
return "soft";
551 case LAZY:
return "lazy";
559 Deoptimizer::Deoptimizer(
Isolate* isolate,
560 JSFunction*
function,
565 Code* optimized_code)
568 bailout_id_(bailout_id),
571 fp_to_sp_delta_(fp_to_sp_delta),
572 has_alignment_padding_(0),
577 deferred_objects_tagged_values_(0),
578 deferred_objects_double_values_(0),
579 deferred_objects_(0),
580 deferred_heap_numbers_(0),
581 jsframe_functions_(0),
582 jsframe_has_adapted_arguments_(0),
583 materialized_values_(
NULL),
584 materialized_objects_(
NULL),
585 materialization_value_index_(0),
586 materialization_object_index_(0),
595 function->shared()->increment_deopt_count();
597 isolate->
counters()->soft_deopts_executed()->Increment();
600 int opt_count =
function->shared()->opt_count();
601 if (opt_count > 0) opt_count--;
602 function->shared()->set_opt_count(opt_count);
605 compiled_code_ = FindOptimizedCode(
function, optimized_code);
610 ASSERT(compiled_code_->
kind() != Code::FUNCTION);
616 : StackFrame::JAVA_SCRIPT;
620 CHECK(AllowHeapAllocation::IsAllowed());
623 unsigned size = ComputeInputFrameSize();
629 Code* Deoptimizer::FindOptimizedCode(JSFunction*
function,
630 Code* optimized_code) {
631 switch (bailout_type_) {
636 return (compiled_code ==
NULL)
641 ASSERT(optimized_code->contains(from_));
642 return optimized_code;
649 void Deoptimizer::PrintFunctionName() {
650 if (function_->IsJSFunction()) {
651 function_->
PrintName(trace_scope_->file());
653 PrintF(trace_scope_->file(),
666 void Deoptimizer::DeleteFrameDescriptions() {
668 for (
int i = 0; i < output_count_; ++i) {
669 if (output_[i] != input_)
delete output_[i];
675 CHECK(!AllowHeapAllocation::IsAllowed());
676 CHECK(disallow_heap_allocation_ !=
NULL);
677 delete disallow_heap_allocation_;
678 disallow_heap_allocation_ =
NULL;
688 if (
id >= kMaxNumberOfEntries)
return NULL;
697 return base->
area_start() + (
id * table_entry_size_);
709 addr >= start + (kMaxNumberOfEntries * table_entry_size_)) {
713 static_cast<int>(addr - start) % table_entry_size_);
714 return static_cast<int>(addr - start) / table_entry_size_;
725 for (
int i = 0; i < length; i++) {
726 if (data->
AstId(i) == id) {
730 PrintF(stderr,
"[couldn't find pc offset for node=%d]\n",
id.ToInt());
738 FATAL(
"unable to find pc offset during deoptimization");
747 while (!context->IsUndefined()) {
750 while (!element->IsUndefined()) {
752 ASSERT(code->
kind() == Code::OPTIMIZED_FUNCTION);
754 element = code->next_code_link();
764 void Deoptimizer::DoComputeOutputFrames() {
766 if (FLAG_log_timer_events &&
767 compiled_code_->
kind() == Code::OPTIMIZED_FUNCTION) {
768 LOG(
isolate(), CodeDeoptEvent(compiled_code_));
774 DeoptimizationInputData* input_data =
777 if (trace_scope_ !=
NULL) {
779 PrintF(trace_scope_->file(),
780 "[deoptimizing (DEOPT %s): begin 0x%08" V8PRIxPTR " ",
782 reinterpret_cast<intptr_t
>(function_));
784 PrintF(trace_scope_->file(),
785 " (opt #%d) @%d, FP to SP delta: %d]\n",
786 input_data->OptimizationId()->value(),
789 if (bailout_type_ ==
EAGER || bailout_type_ ==
SOFT) {
794 BailoutId node_id = input_data->AstId(bailout_id_);
795 ByteArray* translations = input_data->TranslationByteArray();
796 unsigned translation_index =
797 input_data->TranslationIndex(bailout_id_)->value();
800 TranslationIterator iterator(translations, translation_index);
803 ASSERT(Translation::BEGIN == opcode);
807 int count = iterator.Next();
811 for (
int i = 0; i < count; ++i) {
814 output_count_ = count;
817 stack_fp_ =
reinterpret_cast<Address>(
822 for (
int i = 0; i < count; ++i) {
827 case Translation::JS_FRAME:
828 DoComputeJSFrame(&iterator, i);
831 case Translation::ARGUMENTS_ADAPTOR_FRAME:
832 DoComputeArgumentsAdaptorFrame(&iterator, i);
834 case Translation::CONSTRUCT_STUB_FRAME:
835 DoComputeConstructStubFrame(&iterator, i);
837 case Translation::GETTER_STUB_FRAME:
838 DoComputeAccessorStubFrame(&iterator, i,
false);
840 case Translation::SETTER_STUB_FRAME:
841 DoComputeAccessorStubFrame(&iterator, i,
true);
843 case Translation::COMPILED_STUB_FRAME:
844 DoComputeCompiledStubFrame(&iterator, i);
846 case Translation::BEGIN:
848 case Translation::INT32_REGISTER:
849 case Translation::UINT32_REGISTER:
850 case Translation::DOUBLE_REGISTER:
851 case Translation::STACK_SLOT:
852 case Translation::INT32_STACK_SLOT:
853 case Translation::UINT32_STACK_SLOT:
854 case Translation::DOUBLE_STACK_SLOT:
855 case Translation::LITERAL:
856 case Translation::ARGUMENTS_OBJECT:
864 if (trace_scope_ !=
NULL) {
865 double ms = timer.Elapsed().InMillisecondsF();
866 int index = output_count_ - 1;
867 JSFunction*
function = output_[index]->
GetFunction();
868 PrintF(trace_scope_->file(),
869 "[deoptimizing (%s): end 0x%08" V8PRIxPTR " ",
871 reinterpret_cast<intptr_t
>(
function));
873 PrintF(trace_scope_->file(),
874 " @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s,"
878 output_[index]->
GetPc(),
880 static_cast<FullCodeGenerator::State>(
881 output_[index]->GetState()->value())),
882 has_alignment_padding_ ?
"with padding" :
"no padding",
888 void Deoptimizer::DoComputeJSFrame(TranslationIterator* iterator,
890 BailoutId node_id = BailoutId(iterator->Next());
891 JSFunction*
function;
892 if (frame_index != 0) {
895 int closure_id = iterator->Next();
897 ASSERT_EQ(Translation::kSelfLiteralId, closure_id);
898 function = function_;
900 unsigned height = iterator->Next();
902 if (trace_scope_ !=
NULL) {
903 PrintF(trace_scope_->file(),
" translating ");
904 function->PrintName(trace_scope_->file());
905 PrintF(trace_scope_->file(),
906 " => node=%d, height=%d\n", node_id.ToInt(), height_in_bytes);
911 unsigned fixed_frame_size = ComputeFixedSize(
function);
913 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
918 output_frame->SetFrameType(StackFrame::JAVA_SCRIPT);
920 bool is_bottommost = (0 == frame_index);
921 bool is_topmost = (output_count_ - 1 == frame_index);
922 ASSERT(frame_index >= 0 && frame_index < output_count_);
924 output_[frame_index] = output_frame;
931 intptr_t top_address;
934 has_alignment_padding_ = HasAlignmentPadding(
function) ? 1 : 0;
941 height_in_bytes + has_alignment_padding_ * kPointerSize;
943 top_address = output_[frame_index - 1]->
GetTop() - output_frame_size;
945 output_frame->SetTop(top_address);
948 int parameter_count =
function->shared()->formal_parameter_count() + 1;
951 for (
int i = 0; i < parameter_count; ++i) {
953 DoTranslateCommand(iterator, frame_index, output_offset);
971 value = output_[frame_index - 1]->
GetPc();
973 output_frame->SetCallerPc(output_offset, value);
974 if (trace_scope_ !=
NULL) {
975 PrintF(trace_scope_->file(),
976 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
990 value = output_[frame_index - 1]->
GetFp();
992 output_frame->SetCallerFp(output_offset, value);
995 has_alignment_padding_ * kPointerSize) == fp_value);
996 output_frame->SetFp(fp_value);
997 if (is_topmost) output_frame->SetRegister(fp_reg.code(), fp_value);
998 if (trace_scope_ !=
NULL) {
999 PrintF(trace_scope_->file(),
1000 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1004 ASSERT(!is_bottommost || !has_alignment_padding_ ||
1005 (fp_value & kPointerSize) != 0);
1007 if (FLAG_enable_ool_constant_pool) {
1013 if (is_bottommost) {
1018 output_frame->SetCallerConstantPool(output_offset, value);
1022 top_address + output_offset, output_offset, value);
1032 if (is_bottommost) {
1035 value =
reinterpret_cast<intptr_t
>(
function->context());
1037 output_frame->SetFrameSlot(output_offset, value);
1038 output_frame->SetContext(value);
1039 if (is_topmost) output_frame->SetRegister(context_reg.code(), value);
1040 if (trace_scope_ !=
NULL) {
1041 PrintF(trace_scope_->file(),
1042 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1050 value =
reinterpret_cast<intptr_t
>(
function);
1054 output_frame->SetFrameSlot(output_offset, value);
1055 if (trace_scope_ !=
NULL) {
1056 PrintF(trace_scope_->file(),
1057 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1063 for (
unsigned i = 0; i < height; ++i) {
1065 DoTranslateCommand(iterator, frame_index, output_offset);
1067 ASSERT(0 == output_offset);
1070 Code* non_optimized_code =
function->shared()->code();
1071 FixedArray* raw_data = non_optimized_code->deoptimization_data();
1073 Address start = non_optimized_code->instruction_start();
1076 intptr_t pc_value =
reinterpret_cast<intptr_t
>(start + pc_offset);
1077 output_frame->SetPc(pc_value);
1080 if (FLAG_enable_ool_constant_pool) {
1081 intptr_t constant_pool_value =
1082 reinterpret_cast<intptr_t
>(non_optimized_code->constant_pool());
1083 output_frame->SetConstantPool(constant_pool_value);
1085 Register constant_pool_reg =
1087 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
1096 if (is_topmost && bailout_type_ !=
DEBUGGER) {
1097 Builtins* builtins = isolate_->
builtins();
1098 Code* continuation = builtins->
builtin(Builtins::kNotifyDeoptimized);
1099 if (bailout_type_ ==
LAZY) {
1100 continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
1101 }
else if (bailout_type_ ==
SOFT) {
1102 continuation = builtins->builtin(Builtins::kNotifySoftDeoptimized);
1106 output_frame->SetContinuation(
1107 reinterpret_cast<intptr_t>(continuation->entry()));
1112 void Deoptimizer::DoComputeArgumentsAdaptorFrame(TranslationIterator* iterator,
1115 unsigned height = iterator->Next();
1117 if (trace_scope_ !=
NULL) {
1118 PrintF(trace_scope_->file(),
1119 " translating arguments adaptor => height=%d\n", height_in_bytes);
1123 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1131 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
1133 output_[frame_index] = output_frame;
1137 intptr_t top_address;
1138 top_address = output_[frame_index - 1]->
GetTop() - output_frame_size;
1139 output_frame->SetTop(top_address);
1142 int parameter_count = height;
1143 unsigned output_offset = output_frame_size;
1144 for (
int i = 0; i < parameter_count; ++i) {
1146 DoTranslateCommand(iterator, frame_index, output_offset);
1151 intptr_t callers_pc = output_[frame_index - 1]->
GetPc();
1152 output_frame->SetCallerPc(output_offset, callers_pc);
1153 if (trace_scope_ !=
NULL) {
1154 PrintF(trace_scope_->file(),
1155 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1162 intptr_t value = output_[frame_index - 1]->
GetFp();
1163 output_frame->SetCallerFp(output_offset, value);
1165 output_frame->SetFp(fp_value);
1166 if (trace_scope_ !=
NULL) {
1167 PrintF(trace_scope_->file(),
1168 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1173 if (FLAG_enable_ool_constant_pool) {
1177 output_frame->SetCallerConstantPool(output_offset, value);
1181 top_address + output_offset, output_offset, value);
1187 intptr_t context =
reinterpret_cast<intptr_t
>(
1189 output_frame->SetFrameSlot(output_offset, context);
1190 if (trace_scope_ !=
NULL) {
1191 PrintF(trace_scope_->file(),
1192 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1193 V8PRIxPTR " ; context (adaptor sentinel)\n",
1199 value =
reinterpret_cast<intptr_t
>(
function);
1200 output_frame->SetFrameSlot(output_offset, value);
1201 if (trace_scope_ !=
NULL) {
1202 PrintF(trace_scope_->file(),
1203 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1210 value =
reinterpret_cast<intptr_t
>(
Smi::FromInt(height - 1));
1211 output_frame->SetFrameSlot(output_offset, value);
1212 if (trace_scope_ !=
NULL) {
1213 PrintF(trace_scope_->file(),
1214 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1219 ASSERT(0 == output_offset);
1221 Builtins* builtins = isolate_->
builtins();
1222 Code* adaptor_trampoline =
1223 builtins->
builtin(Builtins::kArgumentsAdaptorTrampoline);
1224 intptr_t pc_value =
reinterpret_cast<intptr_t
>(
1225 adaptor_trampoline->instruction_start() +
1226 isolate_->
heap()->arguments_adaptor_deopt_pc_offset()->value());
1227 output_frame->SetPc(pc_value);
1228 if (FLAG_enable_ool_constant_pool) {
1229 intptr_t constant_pool_value =
1230 reinterpret_cast<intptr_t
>(adaptor_trampoline->constant_pool());
1231 output_frame->SetConstantPool(constant_pool_value);
1236 void Deoptimizer::DoComputeConstructStubFrame(TranslationIterator* iterator,
1238 Builtins* builtins = isolate_->
builtins();
1239 Code* construct_stub = builtins->
builtin(Builtins::kJSConstructStubGeneric);
1241 unsigned height = iterator->Next();
1243 if (trace_scope_ !=
NULL) {
1244 PrintF(trace_scope_->file(),
1245 " translating construct stub => height=%d\n", height_in_bytes);
1249 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1254 output_frame->SetFrameType(StackFrame::CONSTRUCT);
1257 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
1259 output_[frame_index] = output_frame;
1263 intptr_t top_address;
1264 top_address = output_[frame_index - 1]->
GetTop() - output_frame_size;
1265 output_frame->SetTop(top_address);
1268 int parameter_count = height;
1269 unsigned output_offset = output_frame_size;
1270 for (
int i = 0; i < parameter_count; ++i) {
1272 int deferred_object_index = deferred_objects_.length();
1273 DoTranslateCommand(iterator, frame_index, output_offset);
1277 if (i == 0 && deferred_objects_.length() > deferred_object_index) {
1278 ASSERT(!deferred_objects_[deferred_object_index].is_arguments());
1279 deferred_objects_[deferred_object_index].patch_slot_address(top_address);
1285 intptr_t callers_pc = output_[frame_index - 1]->
GetPc();
1286 output_frame->SetCallerPc(output_offset, callers_pc);
1287 if (trace_scope_ !=
NULL) {
1288 PrintF(trace_scope_->file(),
1289 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1296 intptr_t value = output_[frame_index - 1]->
GetFp();
1297 output_frame->SetCallerFp(output_offset, value);
1299 output_frame->SetFp(fp_value);
1300 if (trace_scope_ !=
NULL) {
1301 PrintF(trace_scope_->file(),
1302 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1307 if (FLAG_enable_ool_constant_pool) {
1311 output_frame->SetCallerConstantPool(output_offset, value);
1314 V8PRIxPTR " ; caller's constant pool\n",
1315 top_address + output_offset, output_offset, value);
1321 value = output_[frame_index - 1]->
GetContext();
1322 output_frame->SetFrameSlot(output_offset, value);
1323 if (trace_scope_ !=
NULL) {
1324 PrintF(trace_scope_->file(),
1325 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1332 value =
reinterpret_cast<intptr_t
>(
Smi::FromInt(StackFrame::CONSTRUCT));
1333 output_frame->SetFrameSlot(output_offset, value);
1334 if (trace_scope_ !=
NULL) {
1335 PrintF(trace_scope_->file(),
1336 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1337 V8PRIxPTR " ; function (construct sentinel)\n",
1343 value =
reinterpret_cast<intptr_t
>(construct_stub);
1344 output_frame->SetFrameSlot(output_offset, value);
1345 if (trace_scope_ !=
NULL) {
1346 PrintF(trace_scope_->file(),
1347 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1354 value =
reinterpret_cast<intptr_t
>(
Smi::FromInt(height - 1));
1355 output_frame->SetFrameSlot(output_offset, value);
1356 if (trace_scope_ !=
NULL) {
1357 PrintF(trace_scope_->file(),
1358 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1367 value =
reinterpret_cast<intptr_t
>(
function);
1368 output_frame->SetFrameSlot(output_offset, value);
1369 if (trace_scope_ !=
NULL) {
1370 PrintF(trace_scope_->file(),
1371 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1380 value = output_frame->GetFrameSlot(output_frame_size - kPointerSize);
1381 output_frame->SetFrameSlot(output_offset, value);
1382 if (trace_scope_ !=
NULL) {
1383 PrintF(trace_scope_->file(),
1384 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1389 ASSERT(0 == output_offset);
1391 intptr_t
pc =
reinterpret_cast<intptr_t
>(
1392 construct_stub->instruction_start() +
1393 isolate_->
heap()->construct_stub_deopt_pc_offset()->value());
1394 output_frame->SetPc(pc);
1395 if (FLAG_enable_ool_constant_pool) {
1396 intptr_t constant_pool_value =
1397 reinterpret_cast<intptr_t
>(construct_stub->constant_pool());
1398 output_frame->SetConstantPool(constant_pool_value);
1403 void Deoptimizer::DoComputeAccessorStubFrame(TranslationIterator* iterator,
1405 bool is_setter_stub_frame) {
1410 unsigned height = 0;
1412 const char* kind = is_setter_stub_frame ?
"setter" :
"getter";
1413 if (trace_scope_ !=
NULL) {
1414 PrintF(trace_scope_->file(),
1415 " translating %s stub => height=%u\n", kind, height_in_bytes);
1423 unsigned fixed_frame_entries =
1425 (is_setter_stub_frame ? 1 : 0);
1426 unsigned fixed_frame_size = fixed_frame_entries *
kPointerSize;
1427 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1435 ASSERT(frame_index > 0 && frame_index < output_count_ - 1);
1437 output_[frame_index] = output_frame;
1441 intptr_t top_address = output_[frame_index - 1]->
GetTop() - output_frame_size;
1442 output_frame->SetTop(top_address);
1444 unsigned output_offset = output_frame_size;
1448 intptr_t callers_pc = output_[frame_index - 1]->
GetPc();
1449 output_frame->SetCallerPc(output_offset, callers_pc);
1450 if (trace_scope_ !=
NULL) {
1451 PrintF(trace_scope_->file(),
1459 intptr_t value = output_[frame_index - 1]->
GetFp();
1460 output_frame->SetCallerFp(output_offset, value);
1462 output_frame->SetFp(fp_value);
1463 if (trace_scope_ !=
NULL) {
1464 PrintF(trace_scope_->file(),
1470 if (FLAG_enable_ool_constant_pool) {
1474 output_frame->SetCallerConstantPool(output_offset, value);
1477 V8PRIxPTR " ; caller's constant pool\n",
1478 top_address + output_offset, output_offset, value);
1484 value = output_[frame_index - 1]->
GetContext();
1485 output_frame->SetFrameSlot(output_offset, value);
1486 if (trace_scope_ !=
NULL) {
1487 PrintF(trace_scope_->file(),
1496 output_frame->SetFrameSlot(output_offset, value);
1497 if (trace_scope_ !=
NULL) {
1498 PrintF(trace_scope_->file(),
1500 " ; function (%s sentinel)\n",
1507 Builtins::kStoreIC_Setter_ForDeopt :
1508 Builtins::kLoadIC_Getter_ForDeopt;
1510 value =
reinterpret_cast<intptr_t
>(accessor_stub);
1511 output_frame->SetFrameSlot(output_offset, value);
1512 if (trace_scope_ !=
NULL) {
1513 PrintF(trace_scope_->file(),
1522 iterator->Skip(Translation::NumberOfOperandsFor(opcode));
1524 if (is_setter_stub_frame) {
1528 DoTranslateCommand(iterator, frame_index, output_offset);
1531 ASSERT(0 == output_offset);
1533 Smi* offset = is_setter_stub_frame ?
1534 isolate_->
heap()->setter_stub_deopt_pc_offset() :
1535 isolate_->
heap()->getter_stub_deopt_pc_offset();
1536 intptr_t pc =
reinterpret_cast<intptr_t
>(
1537 accessor_stub->instruction_start() + offset->value());
1538 output_frame->SetPc(pc);
1539 if (FLAG_enable_ool_constant_pool) {
1540 intptr_t constant_pool_value =
1541 reinterpret_cast<intptr_t
>(accessor_stub->constant_pool());
1542 output_frame->SetConstantPool(constant_pool_value);
1547 void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator,
1582 compiled_code_->
kind() != Code::OPTIMIZED_FUNCTION);
1583 int major_key = compiled_code_->
major_key();
1584 CodeStubInterfaceDescriptor* descriptor =
1591 ASSERT(descriptor->register_param_count_ >= 0);
1592 int height_in_bytes = kPointerSize * descriptor->register_param_count_ +
1593 sizeof(Arguments) + kPointerSize;
1596 int output_frame_size = height_in_bytes + fixed_frame_size;
1597 if (trace_scope_ !=
NULL) {
1598 PrintF(trace_scope_->file(),
1599 " translating %s => StubFailureTrampolineStub, height=%d\n",
1600 CodeStub::MajorName(static_cast<CodeStub::Major>(major_key),
false),
1607 output_frame->SetFrameType(StackFrame::STUB_FAILURE_TRAMPOLINE);
1608 ASSERT(frame_index == 0);
1609 output_[frame_index] = output_frame;
1615 intptr_t top_address = input_->
GetRegister(fp_reg.code()) -
1617 output_frame->SetTop(top_address);
1621 unsigned output_frame_offset = output_frame_size -
kFPOnStackSize;
1622 intptr_t value = input_->
GetFrameSlot(input_frame_offset);
1623 output_frame->SetCallerPc(output_frame_offset, value);
1624 if (trace_scope_ !=
NULL) {
1625 PrintF(trace_scope_->file(),
1626 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1628 top_address + output_frame_offset, output_frame_offset, value);
1635 output_frame->SetCallerFp(output_frame_offset, value);
1636 intptr_t frame_ptr = input_->
GetRegister(fp_reg.code());
1637 output_frame->SetRegister(fp_reg.code(), frame_ptr);
1638 output_frame->SetFp(frame_ptr);
1639 if (trace_scope_ !=
NULL) {
1640 PrintF(trace_scope_->file(),
1641 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1643 top_address + output_frame_offset, output_frame_offset, value);
1646 if (FLAG_enable_ool_constant_pool) {
1651 output_frame->SetCallerConstantPool(output_frame_offset, value);
1654 V8PRIxPTR " ; caller's constant_pool\n",
1655 top_address + output_frame_offset, output_frame_offset, value);
1663 output_frame->SetRegister(context_reg.code(), value);
1665 output_frame->SetFrameSlot(output_frame_offset, value);
1666 ASSERT(reinterpret_cast<Object*>(value)->IsContext());
1667 if (trace_scope_ !=
NULL) {
1668 PrintF(trace_scope_->file(),
1669 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1671 top_address + output_frame_offset, output_frame_offset, value);
1676 value =
reinterpret_cast<intptr_t
>(
1678 output_frame->SetFrameSlot(output_frame_offset, value);
1679 if (trace_scope_ !=
NULL) {
1680 PrintF(trace_scope_->file(),
1681 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1682 V8PRIxPTR " ; function (stub failure sentinel)\n",
1683 top_address + output_frame_offset, output_frame_offset, value);
1686 intptr_t caller_arg_count = 0;
1687 bool arg_count_known = !descriptor->stack_parameter_count_.is_valid();
1691 int args_arguments_offset = output_frame_offset;
1692 intptr_t the_hole =
reinterpret_cast<intptr_t
>(
1693 isolate_->
heap()->the_hole_value());
1694 if (arg_count_known) {
1696 (caller_arg_count - 1) * kPointerSize;
1701 output_frame->SetFrameSlot(args_arguments_offset, value);
1702 if (trace_scope_ !=
NULL) {
1703 PrintF(trace_scope_->file(),
1704 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1706 top_address + args_arguments_offset, args_arguments_offset, value,
1707 arg_count_known ?
"" :
"(the hole)");
1711 int length_frame_offset = output_frame_offset;
1712 value = arg_count_known ? caller_arg_count : the_hole;
1713 output_frame->SetFrameSlot(length_frame_offset, value);
1714 if (trace_scope_ !=
NULL) {
1715 PrintF(trace_scope_->file(),
1716 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1718 top_address + length_frame_offset, length_frame_offset, value,
1719 arg_count_known ?
"" :
"(the hole)");
1724 (output_frame_size - output_frame_offset) + kPointerSize;
1725 output_frame->SetFrameSlot(output_frame_offset, value);
1726 if (trace_scope_ !=
NULL) {
1727 PrintF(trace_scope_->file(),
1728 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1730 top_address + output_frame_offset, output_frame_offset, value);
1734 int arguments_length_offset = -1;
1735 for (
int i = 0; i < descriptor->register_param_count_; ++i) {
1737 DoTranslateCommand(iterator, 0, output_frame_offset);
1739 if (!arg_count_known && descriptor->IsParameterCountRegister(i)) {
1740 arguments_length_offset = output_frame_offset;
1744 ASSERT(0 == output_frame_offset);
1746 if (!arg_count_known) {
1747 ASSERT(arguments_length_offset >= 0);
1751 Smi* smi_caller_arg_count =
reinterpret_cast<Smi*
>(
1752 output_frame->GetFrameSlot(arguments_length_offset));
1753 caller_arg_count = smi_caller_arg_count->value();
1754 output_frame->SetFrameSlot(length_frame_offset, caller_arg_count);
1755 if (trace_scope_ !=
NULL) {
1756 PrintF(trace_scope_->file(),
1757 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1759 top_address + length_frame_offset, length_frame_offset,
1763 (caller_arg_count - 1) * kPointerSize;
1764 output_frame->SetFrameSlot(args_arguments_offset, value);
1765 if (trace_scope_ !=
NULL) {
1766 PrintF(trace_scope_->file(),
1767 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1769 top_address + args_arguments_offset, args_arguments_offset,
1775 CopyDoubleRegisters(output_frame);
1778 SetPlatformCompiledStubRegisters(output_frame, descriptor);
1781 Code* trampoline =
NULL;
1783 StubFailureTrampolineStub(function_mode).FindCodeInCache(&trampoline,
1786 output_frame->SetPc(reinterpret_cast<intptr_t>(
1787 trampoline->instruction_start()));
1788 if (FLAG_enable_ool_constant_pool) {
1789 Register constant_pool_reg =
1791 intptr_t constant_pool_value =
1792 reinterpret_cast<intptr_t
>(trampoline->constant_pool());
1793 output_frame->SetConstantPool(constant_pool_value);
1794 output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
1797 Code* notify_failure = NotifyStubFailureBuiltin();
1798 output_frame->SetContinuation(
1799 reinterpret_cast<intptr_t>(notify_failure->entry()));
1803 Handle<Object> Deoptimizer::MaterializeNextHeapObject() {
1804 int object_index = materialization_object_index_++;
1805 ObjectMaterializationDescriptor desc = deferred_objects_[object_index];
1806 const int length = desc.object_length();
1808 if (desc.duplicate_object() >= 0) {
1810 object_index = desc.duplicate_object();
1811 materialized_objects_->Add(Handle<Object>());
1812 }
else if (desc.is_arguments() && ArgumentsObjectIsAdapted(object_index)) {
1815 Handle<JSFunction>
function = ArgumentsObjectFunction(object_index);
1818 materialized_objects_->Add(arguments);
1821 for (
int i = 0; i < length; ++i) {
1822 MaterializeNextValue();
1824 }
else if (desc.is_arguments()) {
1827 Handle<JSFunction>
function = ArgumentsObjectFunction(object_index);
1828 Handle<JSObject> arguments =
1831 ASSERT(array->length() == length);
1832 arguments->set_elements(*array);
1833 materialized_objects_->Add(arguments);
1834 for (
int i = 0; i < length; ++i) {
1835 Handle<Object> value = MaterializeNextValue();
1836 array->set(i, *value);
1844 switch (map->instance_type()) {
1848 Handle<Object>
object = MaterializeNextValue();
1849 if (object_index < prev_materialized_count_) {
1850 materialized_objects_->Add(Handle<Object>(
1851 previously_materialized_objects_->get(object_index), isolate_));
1853 materialized_objects_->Add(
object);
1855 materialization_value_index_ +=
kDoubleSize / kPointerSize - 1;
1859 Handle<JSObject>
object =
1861 if (object_index < prev_materialized_count_) {
1862 materialized_objects_->Add(Handle<Object>(
1863 previously_materialized_objects_->get(object_index), isolate_));
1865 materialized_objects_->Add(
object);
1867 Handle<Object> properties = MaterializeNextValue();
1868 Handle<Object> elements = MaterializeNextValue();
1871 for (
int i = 0; i < length - 3; ++i) {
1872 Handle<Object> value = MaterializeNextValue();
1873 object->FastPropertyAtPut(i, *value);
1878 Handle<JSArray>
object =
1880 if (object_index < prev_materialized_count_) {
1881 materialized_objects_->Add(Handle<Object>(
1882 previously_materialized_objects_->get(object_index), isolate_));
1884 materialized_objects_->Add(
object);
1886 Handle<Object> properties = MaterializeNextValue();
1887 Handle<Object> elements = MaterializeNextValue();
1888 Handle<Object> length = MaterializeNextValue();
1891 object->set_length(*length);
1896 "[couldn't handle instance type %d]\n", map->instance_type());
1901 return materialized_objects_->at(object_index);
1905 Handle<Object> Deoptimizer::MaterializeNextValue() {
1906 int value_index = materialization_value_index_++;
1907 Handle<Object> value = materialized_values_->at(value_index);
1908 if (*value == isolate_->
heap()->arguments_marker()) {
1909 value = MaterializeNextHeapObject();
1920 previously_materialized_objects_ = materialized_store->
Get(stack_fp_);
1921 prev_materialized_count_ = previously_materialized_objects_.is_null() ?
1922 0 : previously_materialized_objects_->length();
1925 for (
int frame_index = 0; frame_index <
jsframe_count(); ++frame_index) {
1926 if (frame_index != 0) it->Advance();
1934 for (
int i = 0; i < deferred_objects_tagged_values_.length(); ++i) {
1939 deferred_objects_tagged_values_.Clear();
1944 for (
int i = 0; i < deferred_heap_numbers_.length(); i++) {
1945 HeapNumberMaterializationDescriptor<Address> d = deferred_heap_numbers_[i];
1947 if (trace_scope_ !=
NULL) {
1948 PrintF(trace_scope_->file(),
1949 "Materialized a new heap number %p [%e] in slot %p\n",
1950 reinterpret_cast<void*
>(*num),
1958 for (
int i = 0; i < deferred_objects_double_values_.length(); i++) {
1959 HeapNumberMaterializationDescriptor<int> d =
1960 deferred_objects_double_values_[i];
1962 if (trace_scope_ !=
NULL) {
1963 PrintF(trace_scope_->file(),
1964 "Materialized a new heap number %p [%e] for object at %d\n",
1965 reinterpret_cast<void*
>(*num),
1969 ASSERT(values.at(d.destination())->IsTheHole());
1970 values.Set(d.destination(), num);
1974 deferred_objects_double_values_.Clear();
1977 if (!deferred_objects_.is_empty()) {
1979 materialized_objects_ = &materialized_objects;
1980 materialized_values_ = &values;
1982 while (materialization_object_index_ < deferred_objects_.length()) {
1983 int object_index = materialization_object_index_;
1984 ObjectMaterializationDescriptor descriptor =
1985 deferred_objects_.
at(object_index);
1992 if (trace_scope_ !=
NULL) {
1993 if (descriptor.is_arguments()) {
1994 PrintF(trace_scope_->file(),
1995 "Materialized %sarguments object of length %d for %p: ",
1996 ArgumentsObjectIsAdapted(object_index) ?
"(adapted) " :
"",
1998 reinterpret_cast<void*
>(descriptor.slot_address()));
2000 PrintF(trace_scope_->file(),
2001 "Materialized captured object of size %d for %p: ",
2003 reinterpret_cast<void*
>(descriptor.slot_address()));
2005 object->ShortPrint(trace_scope_->file());
2006 PrintF(trace_scope_->file(),
"\n");
2010 ASSERT(materialization_object_index_ == materialized_objects_->length());
2011 ASSERT(materialization_value_index_ == materialized_values_->length());
2014 if (prev_materialized_count_ > 0) {
2015 materialized_store->
Remove(stack_fp_);
2020 #ifdef ENABLE_DEBUGGER_SUPPORT
2021 void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
2023 uint32_t parameters_size,
2025 uint32_t expressions_size,
2026 DeoptimizedFrameInfo* info) {
2028 Address parameters_bottom = parameters_top + parameters_size;
2029 Address expressions_bottom = expressions_top + expressions_size;
2030 for (
int i = 0; i < deferred_heap_numbers_.length(); i++) {
2031 HeapNumberMaterializationDescriptor<Address> d = deferred_heap_numbers_[i];
2035 Address slot = d.destination();
2036 if (parameters_top <= slot && slot < parameters_bottom) {
2039 int index = (info->parameters_count() - 1) -
2040 static_cast<int>(slot - parameters_top) /
kPointerSize;
2042 if (trace_scope_ !=
NULL) {
2043 PrintF(trace_scope_->file(),
2044 "Materializing a new heap number %p [%e] in slot %p"
2045 "for parameter slot #%d\n",
2046 reinterpret_cast<void*
>(*num),
2052 info->SetParameter(index, *num);
2053 }
else if (expressions_top <= slot && slot < expressions_bottom) {
2056 int index = info->expression_count() - 1 -
2057 static_cast<int>(slot - expressions_top) / kPointerSize;
2059 if (trace_scope_ !=
NULL) {
2060 PrintF(trace_scope_->file(),
2061 "Materializing a new heap number %p [%e] in slot %p"
2062 "for expression slot #%d\n",
2063 reinterpret_cast<void*
>(*num),
2069 info->SetExpression(index, *num);
2076 static const char* TraceValueType(
bool is_smi) {
2081 return "heap number";
2085 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator,
2089 Address object_slot = deferred_objects_[object_index].slot_address();
2095 case Translation::BEGIN:
2096 case Translation::JS_FRAME:
2097 case Translation::ARGUMENTS_ADAPTOR_FRAME:
2098 case Translation::CONSTRUCT_STUB_FRAME:
2099 case Translation::GETTER_STUB_FRAME:
2100 case Translation::SETTER_STUB_FRAME:
2101 case Translation::COMPILED_STUB_FRAME:
2106 int input_reg = iterator->Next();
2107 intptr_t input_value = input_->
GetRegister(input_reg);
2108 if (trace_scope_ !=
NULL) {
2109 PrintF(trace_scope_->file(),
2110 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2111 reinterpret_cast<intptr_t
>(object_slot),
2113 PrintF(trace_scope_->file(),
2114 "0x%08" V8PRIxPTR " ; %s ", input_value,
2116 reinterpret_cast<Object*
>(input_value)->ShortPrint(
2117 trace_scope_->file());
2118 PrintF(trace_scope_->file(),
2121 AddObjectTaggedValue(input_value);
2125 case Translation::INT32_REGISTER: {
2126 int input_reg = iterator->Next();
2129 if (trace_scope_ !=
NULL) {
2130 PrintF(trace_scope_->file(),
2131 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2132 reinterpret_cast<intptr_t
>(object_slot),
2134 PrintF(trace_scope_->file(),
2137 TraceValueType(is_smi));
2140 intptr_t tagged_value =
2141 reinterpret_cast<intptr_t
>(
Smi::FromInt(static_cast<int>(value)));
2142 AddObjectTaggedValue(tagged_value);
2144 double double_value =
static_cast<double>(
static_cast<int32_t>(value));
2145 AddObjectDoubleValue(double_value);
2150 case Translation::UINT32_REGISTER: {
2151 int input_reg = iterator->Next();
2152 uintptr_t value =
static_cast<uintptr_t
>(input_->
GetRegister(input_reg));
2154 if (trace_scope_ !=
NULL) {
2155 PrintF(trace_scope_->file(),
2156 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2157 reinterpret_cast<intptr_t
>(object_slot),
2159 PrintF(trace_scope_->file(),
2160 "%" V8PRIdPTR " ; uint %s (%s)\n", value,
2162 TraceValueType(is_smi));
2165 intptr_t tagged_value =
2166 reinterpret_cast<intptr_t
>(
Smi::FromInt(static_cast<int>(value)));
2167 AddObjectTaggedValue(tagged_value);
2169 double double_value =
static_cast<double>(
static_cast<uint32_t
>(value));
2170 AddObjectDoubleValue(double_value);
2175 case Translation::DOUBLE_REGISTER: {
2176 int input_reg = iterator->Next();
2178 if (trace_scope_ !=
NULL) {
2179 PrintF(trace_scope_->file(),
2180 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2181 reinterpret_cast<intptr_t
>(object_slot),
2183 PrintF(trace_scope_->file(),
2187 AddObjectDoubleValue(value);
2191 case Translation::STACK_SLOT: {
2192 int input_slot_index = iterator->Next();
2194 intptr_t input_value = input_->
GetFrameSlot(input_offset);
2195 if (trace_scope_ !=
NULL) {
2196 PrintF(trace_scope_->file(),
2197 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2198 reinterpret_cast<intptr_t
>(object_slot),
2200 PrintF(trace_scope_->file(),
2202 reinterpret_cast<Object*
>(input_value)->ShortPrint(
2203 trace_scope_->file());
2204 PrintF(trace_scope_->file(),
2207 AddObjectTaggedValue(input_value);
2211 case Translation::INT32_STACK_SLOT: {
2212 int input_slot_index = iterator->Next();
2216 if (trace_scope_ !=
NULL) {
2217 PrintF(trace_scope_->file(),
2218 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2219 reinterpret_cast<intptr_t
>(object_slot),
2221 PrintF(trace_scope_->file(),
2226 intptr_t tagged_value =
2227 reinterpret_cast<intptr_t
>(
Smi::FromInt(static_cast<int>(value)));
2228 AddObjectTaggedValue(tagged_value);
2230 double double_value =
static_cast<double>(
static_cast<int32_t>(value));
2231 AddObjectDoubleValue(double_value);
2236 case Translation::UINT32_STACK_SLOT: {
2237 int input_slot_index = iterator->Next();
2240 static_cast<uintptr_t
>(input_->
GetFrameSlot(input_offset));
2242 if (trace_scope_ !=
NULL) {
2243 PrintF(trace_scope_->file(),
2244 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2245 reinterpret_cast<intptr_t
>(object_slot),
2247 PrintF(trace_scope_->file(),
2248 "%" V8PRIdPTR " ; [sp + %d] (uint %s)\n",
2252 intptr_t tagged_value =
2253 reinterpret_cast<intptr_t
>(
Smi::FromInt(static_cast<int>(value)));
2254 AddObjectTaggedValue(tagged_value);
2256 double double_value =
static_cast<double>(
static_cast<uint32_t
>(value));
2257 AddObjectDoubleValue(double_value);
2262 case Translation::DOUBLE_STACK_SLOT: {
2263 int input_slot_index = iterator->Next();
2266 if (trace_scope_ !=
NULL) {
2267 PrintF(trace_scope_->file(),
2268 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2269 reinterpret_cast<intptr_t
>(object_slot),
2271 PrintF(trace_scope_->file(),
2274 AddObjectDoubleValue(value);
2278 case Translation::LITERAL: {
2279 Object* literal = ComputeLiteral(iterator->Next());
2280 if (trace_scope_ !=
NULL) {
2281 PrintF(trace_scope_->file(),
2282 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2283 reinterpret_cast<intptr_t
>(object_slot),
2285 literal->ShortPrint(trace_scope_->file());
2286 PrintF(trace_scope_->file(),
2289 intptr_t value =
reinterpret_cast<intptr_t
>(literal);
2290 AddObjectTaggedValue(value);
2294 case Translation::DUPLICATED_OBJECT: {
2295 int object_index = iterator->Next();
2296 if (trace_scope_ !=
NULL) {
2297 PrintF(trace_scope_->file(),
2298 " nested @0x%08" V8PRIxPTR ": [field #%d] <- ",
2299 reinterpret_cast<intptr_t
>(object_slot),
2301 isolate_->
heap()->arguments_marker()->ShortPrint(trace_scope_->file());
2302 PrintF(trace_scope_->file(),
2303 " ; duplicate of object #%d\n", object_index);
2307 intptr_t value =
reinterpret_cast<intptr_t
>(
2308 isolate_->
heap()->arguments_marker());
2309 AddObjectDuplication(0, object_index);
2310 AddObjectTaggedValue(value);
2314 case Translation::ARGUMENTS_OBJECT:
2315 case Translation::CAPTURED_OBJECT: {
2316 int length = iterator->Next();
2317 bool is_args = opcode == Translation::ARGUMENTS_OBJECT;
2318 if (trace_scope_ !=
NULL) {
2319 PrintF(trace_scope_->file(),
2320 " nested @0x%08" V8PRIxPTR ": [field #%d] <- ",
2321 reinterpret_cast<intptr_t
>(object_slot),
2323 isolate_->
heap()->arguments_marker()->ShortPrint(trace_scope_->file());
2324 PrintF(trace_scope_->file(),
2325 " ; object (length = %d, is_args = %d)\n", length, is_args);
2329 intptr_t value =
reinterpret_cast<intptr_t
>(
2330 isolate_->
heap()->arguments_marker());
2331 AddObjectStart(0, length, is_args);
2332 AddObjectTaggedValue(value);
2335 int object_index = deferred_objects_.length() - 1;
2336 for (
int i = 0; i < length; i++) {
2337 DoTranslateObject(iterator, object_index, i);
2345 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
2347 unsigned output_offset) {
2350 const intptr_t kPlaceholder =
reinterpret_cast<intptr_t
>(
Smi::FromInt(0));
2356 case Translation::BEGIN:
2357 case Translation::JS_FRAME:
2358 case Translation::ARGUMENTS_ADAPTOR_FRAME:
2359 case Translation::CONSTRUCT_STUB_FRAME:
2360 case Translation::GETTER_STUB_FRAME:
2361 case Translation::SETTER_STUB_FRAME:
2362 case Translation::COMPILED_STUB_FRAME:
2367 int input_reg = iterator->Next();
2368 intptr_t input_value = input_->
GetRegister(input_reg);
2369 if (trace_scope_ !=
NULL) {
2371 trace_scope_->file(),
2377 reinterpret_cast<Object*
>(input_value)->ShortPrint(
2378 trace_scope_->file());
2379 PrintF(trace_scope_->file(),
"\n");
2381 output_[frame_index]->
SetFrameSlot(output_offset, input_value);
2385 case Translation::INT32_REGISTER: {
2386 int input_reg = iterator->Next();
2389 if (trace_scope_ !=
NULL) {
2391 trace_scope_->file(),
2392 " 0x%08" V8PRIxPTR
": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n",
2397 TraceValueType(is_smi));
2400 intptr_t tagged_value =
2401 reinterpret_cast<intptr_t
>(
Smi::FromInt(static_cast<int>(value)));
2402 output_[frame_index]->
SetFrameSlot(output_offset, tagged_value);
2406 AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
2407 static_cast<double>(static_cast<int32_t>(value)));
2408 output_[frame_index]->
SetFrameSlot(output_offset, kPlaceholder);
2413 case Translation::UINT32_REGISTER: {
2414 int input_reg = iterator->Next();
2415 uintptr_t value =
static_cast<uintptr_t
>(input_->
GetRegister(input_reg));
2417 if (trace_scope_ !=
NULL) {
2419 trace_scope_->file(),
2420 " 0x%08" V8PRIxPTR
": [top + %d] <- %" V8PRIuPTR
2421 " ; uint %s (%s)\n",
2426 TraceValueType(is_smi));
2429 intptr_t tagged_value =
2430 reinterpret_cast<intptr_t
>(
Smi::FromInt(static_cast<int>(value)));
2431 output_[frame_index]->
SetFrameSlot(output_offset, tagged_value);
2435 AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
2436 static_cast<double>(static_cast<uint32_t>(value)));
2437 output_[frame_index]->
SetFrameSlot(output_offset, kPlaceholder);
2442 case Translation::DOUBLE_REGISTER: {
2443 int input_reg = iterator->Next();
2445 if (trace_scope_ !=
NULL) {
2446 PrintF(trace_scope_->file(),
2447 " 0x%08" V8PRIxPTR
": [top + %d] <- %e ; %s\n",
2455 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value);
2456 output_[frame_index]->
SetFrameSlot(output_offset, kPlaceholder);
2460 case Translation::STACK_SLOT: {
2461 int input_slot_index = iterator->Next();
2463 intptr_t input_value = input_->
GetFrameSlot(input_offset);
2464 if (trace_scope_ !=
NULL) {
2465 PrintF(trace_scope_->file(),
2466 " 0x%08" V8PRIxPTR
": ",
2468 PrintF(trace_scope_->file(),
2469 "[top + %d] <- 0x%08" V8PRIxPTR
" ; [sp + %d] ",
2473 reinterpret_cast<Object*
>(input_value)->ShortPrint(
2474 trace_scope_->file());
2475 PrintF(trace_scope_->file(),
"\n");
2477 output_[frame_index]->
SetFrameSlot(output_offset, input_value);
2481 case Translation::INT32_STACK_SLOT: {
2482 int input_slot_index = iterator->Next();
2486 if (trace_scope_ !=
NULL) {
2487 PrintF(trace_scope_->file(),
2488 " 0x%08" V8PRIxPTR
": ",
2490 PrintF(trace_scope_->file(),
2491 "[top + %d] <- %" V8PRIdPTR
" ; [sp + %d] (%s)\n",
2495 TraceValueType(is_smi));
2498 intptr_t tagged_value =
2499 reinterpret_cast<intptr_t
>(
Smi::FromInt(static_cast<int>(value)));
2500 output_[frame_index]->
SetFrameSlot(output_offset, tagged_value);
2504 AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
2505 static_cast<double>(static_cast<int32_t>(value)));
2506 output_[frame_index]->
SetFrameSlot(output_offset, kPlaceholder);
2511 case Translation::UINT32_STACK_SLOT: {
2512 int input_slot_index = iterator->Next();
2515 static_cast<uintptr_t
>(input_->
GetFrameSlot(input_offset));
2517 if (trace_scope_ !=
NULL) {
2518 PrintF(trace_scope_->file(),
2519 " 0x%08" V8PRIxPTR
": ",
2521 PrintF(trace_scope_->file(),
2522 "[top + %d] <- %" V8PRIuPTR
" ; [sp + %d] (uint32 %s)\n",
2526 TraceValueType(is_smi));
2529 intptr_t tagged_value =
2530 reinterpret_cast<intptr_t
>(
Smi::FromInt(static_cast<int>(value)));
2531 output_[frame_index]->
SetFrameSlot(output_offset, tagged_value);
2535 AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
2536 static_cast<double>(static_cast<uint32_t>(value)));
2537 output_[frame_index]->
SetFrameSlot(output_offset, kPlaceholder);
2542 case Translation::DOUBLE_STACK_SLOT: {
2543 int input_slot_index = iterator->Next();
2546 if (trace_scope_ !=
NULL) {
2547 PrintF(trace_scope_->file(),
2548 " 0x%08" V8PRIxPTR
": [top + %d] <- %e ; [sp + %d]\n",
2556 AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value);
2557 output_[frame_index]->
SetFrameSlot(output_offset, kPlaceholder);
2561 case Translation::LITERAL: {
2562 Object* literal = ComputeLiteral(iterator->Next());
2563 if (trace_scope_ !=
NULL) {
2564 PrintF(trace_scope_->file(),
2565 " 0x%08" V8PRIxPTR
": [top + %d] <- ",
2568 literal->ShortPrint(trace_scope_->file());
2569 PrintF(trace_scope_->file(),
" ; literal\n");
2571 intptr_t value =
reinterpret_cast<intptr_t
>(literal);
2572 output_[frame_index]->
SetFrameSlot(output_offset, value);
2576 case Translation::DUPLICATED_OBJECT: {
2577 int object_index = iterator->Next();
2578 if (trace_scope_ !=
NULL) {
2579 PrintF(trace_scope_->file(),
2580 " 0x%08" V8PRIxPTR
": [top + %d] <- ",
2583 isolate_->
heap()->arguments_marker()->ShortPrint(trace_scope_->file());
2584 PrintF(trace_scope_->file(),
2585 " ; duplicate of object #%d\n", object_index);
2589 intptr_t value =
reinterpret_cast<intptr_t
>(
2590 isolate_->
heap()->arguments_marker());
2591 AddObjectDuplication(output_[frame_index]->GetTop() + output_offset,
2593 output_[frame_index]->
SetFrameSlot(output_offset, value);
2597 case Translation::ARGUMENTS_OBJECT:
2598 case Translation::CAPTURED_OBJECT: {
2599 int length = iterator->Next();
2600 bool is_args = opcode == Translation::ARGUMENTS_OBJECT;
2601 if (trace_scope_ !=
NULL) {
2602 PrintF(trace_scope_->file(),
2603 " 0x%08" V8PRIxPTR
": [top + %d] <- ",
2606 isolate_->
heap()->arguments_marker()->ShortPrint(trace_scope_->file());
2607 PrintF(trace_scope_->file(),
2608 " ; object (length = %d, is_args = %d)\n", length, is_args);
2612 intptr_t value =
reinterpret_cast<intptr_t
>(
2613 isolate_->
heap()->arguments_marker());
2614 AddObjectStart(output_[frame_index]->GetTop() + output_offset,
2616 output_[frame_index]->
SetFrameSlot(output_offset, value);
2619 int object_index = deferred_objects_.length() - 1;
2620 for (
int i = 0; i < length; i++) {
2621 DoTranslateObject(iterator, object_index, i);
2629 unsigned Deoptimizer::ComputeInputFrameSize()
const {
2630 unsigned fixed_size = ComputeFixedSize(function_);
2633 unsigned result = fixed_size + fp_to_sp_delta_ -
2636 if (compiled_code_->
kind() == Code::OPTIMIZED_FUNCTION) {
2637 unsigned stack_slots = compiled_code_->
stack_slots();
2638 unsigned outgoing_size = ComputeOutgoingArgumentSize();
2639 ASSERT(result == fixed_size + (stack_slots * kPointerSize) + outgoing_size);
2646 unsigned Deoptimizer::ComputeFixedSize(JSFunction*
function)
const {
2649 return ComputeIncomingArgumentSize(
function) +
2654 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction*
function)
const {
2661 unsigned arguments =
function->shared()->formal_parameter_count() + 1;
2666 unsigned Deoptimizer::ComputeOutgoingArgumentSize()
const {
2668 compiled_code_->deoptimization_data());
2669 unsigned height = data->ArgumentsStackHeight(bailout_id_)->value();
2674 Object* Deoptimizer::ComputeLiteral(
int index)
const {
2676 compiled_code_->deoptimization_data());
2677 FixedArray*
literals = data->LiteralArray();
2678 return literals->get(index);
2682 void Deoptimizer::AddObjectStart(intptr_t slot,
int length,
bool is_args) {
2683 ObjectMaterializationDescriptor object_desc(
2684 reinterpret_cast<Address>(slot), jsframe_count_, length, -1, is_args);
2685 deferred_objects_.
Add(object_desc);
2689 void Deoptimizer::AddObjectDuplication(intptr_t slot,
int object_index) {
2690 ObjectMaterializationDescriptor object_desc(
2691 reinterpret_cast<Address>(slot), jsframe_count_, -1, object_index,
false);
2692 deferred_objects_.
Add(object_desc);
2696 void Deoptimizer::AddObjectTaggedValue(intptr_t value) {
2697 deferred_objects_tagged_values_.
Add(reinterpret_cast<Object*>(value));
2701 void Deoptimizer::AddObjectDoubleValue(
double value) {
2702 deferred_objects_tagged_values_.
Add(
isolate()->heap()->the_hole_value());
2703 HeapNumberMaterializationDescriptor<int> value_desc(
2704 deferred_objects_tagged_values_.length() - 1, value);
2705 deferred_objects_double_values_.
Add(value_desc);
2709 void Deoptimizer::AddDoubleValue(intptr_t slot_address,
double value) {
2710 HeapNumberMaterializationDescriptor<Address> value_desc(
2711 reinterpret_cast<Address>(slot_address), value);
2712 deferred_heap_numbers_.
Add(value_desc);
2725 int entry_count = data->deopt_entry_code_entries_[type];
2726 if (max_entry_id < entry_count)
return;
2727 entry_count =
Max(entry_count, Deoptimizer::kMinNumberOfEntries);
2728 while (max_entry_id >= entry_count) entry_count *= 2;
2729 ASSERT(entry_count <= Deoptimizer::kMaxNumberOfEntries);
2733 GenerateDeoptimizationEntries(&masm, entry_count, type);
2736 ASSERT(!RelocInfo::RequiresRelocation(desc));
2738 MemoryChunk* chunk = data->deopt_entry_code_[type];
2746 data->deopt_entry_code_entries_[type] = entry_count;
2751 JSFunction*
function)
2752 : frame_size_(frame_size),
2753 function_(function),
2757 context_(kZapUint32),
2758 constant_pool_(kZapUint32) {
2768 for (
unsigned o = 0; o < frame_size; o +=
kPointerSize) {
2774 int FrameDescription::ComputeFixedSize() {
2781 if (slot_index >= 0) {
2785 return base - ((slot_index + 1) * kPointerSize);
2790 return base - ((slot_index + 1) * kPointerSize);
2797 case StackFrame::JAVA_SCRIPT:
2798 return function_->shared()->formal_parameter_count();
2802 return reinterpret_cast<Smi*
>(*GetFrameSlotPointer(0))->value();
2818 return reinterpret_cast<Object*
>(*GetFrameSlotPointer(offset));
2823 ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_);
2830 ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_);
2832 return reinterpret_cast<Object*
>(*GetFrameSlotPointer(offset));
2836 void TranslationBuffer::Add(
int32_t value,
Zone* zone) {
2838 bool is_negative = (value < 0);
2839 uint32_t bits = ((is_negative ? -value : value) << 1) |
2840 static_cast<int32_t>(is_negative);
2844 uint32_t next = bits >> 7;
2845 contents_.Add(((bits << 1) & 0xFF) | (next != 0), zone);
2847 }
while (bits != 0);
2851 int32_t TranslationIterator::Next() {
2855 for (
int i = 0;
true; i += 7) {
2857 uint8_t next = buffer_->get(index_++);
2858 bits |= (next >> 1) << i;
2859 if ((next & 1) == 0)
break;
2862 bool is_negative = (bits & 1) == 1;
2864 return is_negative ? -result : result;
2868 Handle<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) {
2869 int length = contents_.length();
2870 Handle<ByteArray> result = factory->NewByteArray(length,
TENURED);
2872 result->GetDataStartAddress(), contents_.ToVector().start(), length);
2877 void Translation::BeginConstructStubFrame(
int literal_id,
unsigned height) {
2878 buffer_->Add(CONSTRUCT_STUB_FRAME, zone());
2879 buffer_->Add(literal_id, zone());
2880 buffer_->Add(height, zone());
2884 void Translation::BeginGetterStubFrame(
int literal_id) {
2885 buffer_->Add(GETTER_STUB_FRAME, zone());
2886 buffer_->Add(literal_id, zone());
2890 void Translation::BeginSetterStubFrame(
int literal_id) {
2891 buffer_->Add(SETTER_STUB_FRAME, zone());
2892 buffer_->Add(literal_id, zone());
2896 void Translation::BeginArgumentsAdaptorFrame(
int literal_id,
unsigned height) {
2897 buffer_->Add(ARGUMENTS_ADAPTOR_FRAME, zone());
2898 buffer_->Add(literal_id, zone());
2899 buffer_->Add(height, zone());
2903 void Translation::BeginJSFrame(BailoutId node_id,
2906 buffer_->Add(JS_FRAME, zone());
2907 buffer_->Add(node_id.ToInt(), zone());
2908 buffer_->Add(literal_id, zone());
2909 buffer_->Add(height, zone());
2913 void Translation::BeginCompiledStubFrame() {
2914 buffer_->Add(COMPILED_STUB_FRAME, zone());
2918 void Translation::BeginArgumentsObject(
int args_length) {
2919 buffer_->Add(ARGUMENTS_OBJECT, zone());
2920 buffer_->Add(args_length, zone());
2924 void Translation::BeginCapturedObject(
int length) {
2925 buffer_->Add(CAPTURED_OBJECT, zone());
2926 buffer_->Add(length, zone());
2930 void Translation::DuplicateObject(
int object_index) {
2931 buffer_->Add(DUPLICATED_OBJECT, zone());
2932 buffer_->Add(object_index, zone());
2936 void Translation::StoreRegister(Register reg) {
2938 buffer_->Add(reg.code(), zone());
2942 void Translation::StoreInt32Register(Register reg) {
2943 buffer_->Add(INT32_REGISTER, zone());
2944 buffer_->Add(reg.code(), zone());
2948 void Translation::StoreUint32Register(Register reg) {
2949 buffer_->Add(UINT32_REGISTER, zone());
2950 buffer_->Add(reg.code(), zone());
2955 buffer_->Add(DOUBLE_REGISTER, zone());
2960 void Translation::StoreStackSlot(
int index) {
2961 buffer_->Add(STACK_SLOT, zone());
2962 buffer_->Add(index, zone());
2966 void Translation::StoreInt32StackSlot(
int index) {
2967 buffer_->Add(INT32_STACK_SLOT, zone());
2968 buffer_->Add(index, zone());
2972 void Translation::StoreUint32StackSlot(
int index) {
2973 buffer_->Add(UINT32_STACK_SLOT, zone());
2974 buffer_->Add(index, zone());
2978 void Translation::StoreDoubleStackSlot(
int index) {
2979 buffer_->Add(DOUBLE_STACK_SLOT, zone());
2980 buffer_->Add(index, zone());
2984 void Translation::StoreLiteral(
int literal_id) {
2985 buffer_->Add(LITERAL, zone());
2986 buffer_->Add(literal_id, zone());
2990 void Translation::StoreArgumentsObject(
bool args_known,
2993 buffer_->Add(ARGUMENTS_OBJECT, zone());
2994 buffer_->Add(args_known, zone());
2995 buffer_->Add(args_index, zone());
2996 buffer_->Add(args_length, zone());
3000 int Translation::NumberOfOperandsFor(
Opcode opcode) {
3002 case GETTER_STUB_FRAME:
3003 case SETTER_STUB_FRAME:
3004 case DUPLICATED_OBJECT:
3005 case ARGUMENTS_OBJECT:
3006 case CAPTURED_OBJECT:
3008 case INT32_REGISTER:
3009 case UINT32_REGISTER:
3010 case DOUBLE_REGISTER:
3012 case INT32_STACK_SLOT:
3013 case UINT32_STACK_SLOT:
3014 case DOUBLE_STACK_SLOT:
3016 case COMPILED_STUB_FRAME:
3019 case ARGUMENTS_ADAPTOR_FRAME:
3020 case CONSTRUCT_STUB_FRAME:
3030 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
3032 const char* Translation::StringFor(
Opcode opcode) {
3033 #define TRANSLATION_OPCODE_CASE(item) case item: return #item;
3037 #undef TRANSLATION_OPCODE_CASE
3048 SlotRef SlotRefValueBuilder::ComputeSlotForNextArgument(
3050 TranslationIterator* iterator,
3051 DeoptimizationInputData* data,
3052 JavaScriptFrame* frame) {
3054 case Translation::BEGIN:
3055 case Translation::JS_FRAME:
3056 case Translation::ARGUMENTS_ADAPTOR_FRAME:
3057 case Translation::CONSTRUCT_STUB_FRAME:
3058 case Translation::GETTER_STUB_FRAME:
3059 case Translation::SETTER_STUB_FRAME:
3063 case Translation::DUPLICATED_OBJECT: {
3064 return SlotRef::NewDuplicateObject(iterator->Next());
3067 case Translation::ARGUMENTS_OBJECT:
3068 return SlotRef::NewArgumentsObject(iterator->Next());
3070 case Translation::CAPTURED_OBJECT: {
3071 return SlotRef::NewDeferredObject(iterator->Next());
3075 case Translation::INT32_REGISTER:
3076 case Translation::UINT32_REGISTER:
3077 case Translation::DOUBLE_REGISTER:
3083 case Translation::STACK_SLOT: {
3084 int slot_index = iterator->Next();
3085 Address slot_addr = SlotAddress(frame, slot_index);
3086 return SlotRef(slot_addr, SlotRef::TAGGED);
3089 case Translation::INT32_STACK_SLOT: {
3090 int slot_index = iterator->Next();
3091 Address slot_addr = SlotAddress(frame, slot_index);
3092 return SlotRef(slot_addr, SlotRef::INT32);
3095 case Translation::UINT32_STACK_SLOT: {
3096 int slot_index = iterator->Next();
3097 Address slot_addr = SlotAddress(frame, slot_index);
3098 return SlotRef(slot_addr, SlotRef::UINT32);
3101 case Translation::DOUBLE_STACK_SLOT: {
3102 int slot_index = iterator->Next();
3103 Address slot_addr = SlotAddress(frame, slot_index);
3104 return SlotRef(slot_addr, SlotRef::DOUBLE);
3107 case Translation::LITERAL: {
3108 int literal_index = iterator->Next();
3109 return SlotRef(data->GetIsolate(),
3110 data->LiteralArray()->get(literal_index));
3113 case Translation::COMPILED_STUB_FRAME:
3118 FATAL(
"We should never get here - unexpected deopt info.");
3123 SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame,
3124 int inlined_jsframe_index,
3126 : current_slot_(0), args_length_(-1), first_slot_index_(-1) {
3129 int deopt_index = Safepoint::kNoDeoptimizationIndex;
3130 DeoptimizationInputData* data =
3131 static_cast<OptimizedFrame*
>(frame)->GetDeoptimizationData(&deopt_index);
3132 TranslationIterator it(data->TranslationByteArray(),
3133 data->TranslationIndex(deopt_index)->value());
3135 ASSERT(opcode == Translation::BEGIN);
3138 stack_frame_id_ = frame->fp();
3140 int jsframe_count = it.Next();
3142 ASSERT(jsframe_count > inlined_jsframe_index);
3143 int jsframes_to_skip = inlined_jsframe_index;
3144 int number_of_slots = -1;
3145 bool should_deopt =
false;
3146 while (number_of_slots != 0) {
3148 bool processed =
false;
3149 if (opcode == Translation::ARGUMENTS_ADAPTOR_FRAME) {
3150 if (jsframes_to_skip == 0) {
3151 ASSERT(Translation::NumberOfOperandsFor(opcode) == 2);
3154 int height = it.Next();
3157 it.Skip(Translation::NumberOfOperandsFor(
3158 static_cast<Translation::Opcode>(it.Next())));
3162 first_slot_index_ = slot_refs_.length();
3163 args_length_ = height - 1;
3164 number_of_slots = height - 1;
3167 }
else if (opcode == Translation::JS_FRAME) {
3168 if (jsframes_to_skip == 0) {
3170 it.Skip(Translation::NumberOfOperandsFor(opcode));
3173 it.Skip(Translation::NumberOfOperandsFor(
3174 static_cast<Translation::Opcode>(it.Next())));
3180 first_slot_index_ = slot_refs_.length();
3186 }
else if (opcode != Translation::BEGIN &&
3187 opcode != Translation::CONSTRUCT_STUB_FRAME &&
3188 opcode != Translation::GETTER_STUB_FRAME &&
3189 opcode != Translation::SETTER_STUB_FRAME &&
3190 opcode != Translation::COMPILED_STUB_FRAME) {
3191 slot_refs_.Add(ComputeSlotForNextArgument(opcode, &it, data, frame));
3193 if (first_slot_index_ >= 0) {
3197 SlotRef& slot = slot_refs_.last();
3198 ASSERT(slot.Representation() != SlotRef::ARGUMENTS_OBJECT);
3199 number_of_slots += slot.GetChildrenCount();
3200 if (slot.Representation() == SlotRef::DEFERRED_OBJECT ||
3201 slot.Representation() == SlotRef::DUPLICATE_OBJECT) {
3202 should_deopt =
true;
3210 it.Skip(Translation::NumberOfOperandsFor(opcode));
3214 List<JSFunction*> functions(2);
3215 frame->GetFunctions(&functions);
3221 Handle<Object> SlotRef::GetValue(Isolate* isolate) {
3222 switch (representation_) {
3231 return isolate->factory()->NewNumberFromInt(value);
3238 return Handle<Object>(
Smi::FromInt(static_cast<int>(value)), isolate);
3240 return isolate->factory()->NewNumber(static_cast<double>(value));
3245 double value = read_double_value(addr_);
3246 return isolate->factory()->NewNumber(value);
3253 FATAL(
"We should never get here - unexpected deopt info.");
3259 void SlotRefValueBuilder::Prepare(Isolate* isolate) {
3260 MaterializedObjectStore* materialized_store =
3261 isolate->materialized_object_store();
3262 previously_materialized_objects_ = materialized_store->Get(stack_frame_id_);
3263 prev_materialized_count_ = previously_materialized_objects_.is_null()
3264 ? 0 : previously_materialized_objects_->length();
3269 while (current_slot_ < first_slot_index_) {
3270 GetNext(isolate, 0);
3272 ASSERT(current_slot_ == first_slot_index_);
3276 Handle<Object> SlotRefValueBuilder::GetPreviouslyMaterialized(
3277 Isolate* isolate,
int length) {
3278 int object_index = materialized_objects_.length();
3279 Handle<Object> return_value = Handle<Object>(
3280 previously_materialized_objects_->get(object_index), isolate);
3281 materialized_objects_.Add(return_value);
3285 for (
int i = 0; i < length; i++) {
3286 SlotRef& slot = slot_refs_[current_slot_];
3291 length += slot.GetChildrenCount();
3295 if (slot.Representation() == SlotRef::DEFERRED_OBJECT ||
3296 slot.Representation() == SlotRef::DUPLICATE_OBJECT) {
3297 int nested_object_index = materialized_objects_.length();
3298 Handle<Object> nested_object = Handle<Object>(
3299 previously_materialized_objects_->get(nested_object_index),
3301 materialized_objects_.Add(nested_object);
3305 return return_value;
3309 Handle<Object> SlotRefValueBuilder::GetNext(Isolate* isolate,
int lvl) {
3310 SlotRef& slot = slot_refs_[current_slot_];
3312 switch (slot.Representation()) {
3313 case SlotRef::TAGGED:
3314 case SlotRef::INT32:
3315 case SlotRef::UINT32:
3316 case SlotRef::DOUBLE:
3317 case SlotRef::LITERAL: {
3318 return slot.GetValue(isolate);
3320 case SlotRef::ARGUMENTS_OBJECT: {
3324 materialized_objects_.Add(isolate->factory()->undefined_value());
3325 int length = slot.GetChildrenCount();
3326 for (
int i = 0; i < length; ++i) {
3328 GetNext(isolate, lvl + 1);
3330 return isolate->factory()->undefined_value();
3332 case SlotRef::DEFERRED_OBJECT: {
3333 int length = slot.GetChildrenCount();
3334 ASSERT(slot_refs_[current_slot_].Representation() == SlotRef::LITERAL ||
3335 slot_refs_[current_slot_].Representation() == SlotRef::TAGGED);
3337 int object_index = materialized_objects_.length();
3338 if (object_index < prev_materialized_count_) {
3339 return GetPreviouslyMaterialized(isolate, length);
3342 Handle<Object> map_object = slot_refs_[current_slot_].GetValue(isolate);
3348 switch (map->instance_type()) {
3352 Handle<Object>
object = GetNext(isolate, lvl + 1);
3353 materialized_objects_.Add(
object);
3358 for (
int i = 0; i < length - 2; i++) {
3359 GetNext(isolate, lvl + 1);
3364 Handle<JSObject>
object =
3365 isolate->factory()->NewJSObjectFromMap(map,
NOT_TENURED,
false);
3366 materialized_objects_.Add(
object);
3367 Handle<Object> properties = GetNext(isolate, lvl + 1);
3368 Handle<Object> elements = GetNext(isolate, lvl + 1);
3371 for (
int i = 0; i < length - 3; ++i) {
3372 Handle<Object> value = GetNext(isolate, lvl + 1);
3373 object->FastPropertyAtPut(i, *value);
3378 Handle<JSArray>
object =
3379 isolate->factory()->NewJSArray(0, map->elements_kind());
3380 materialized_objects_.Add(
object);
3381 Handle<Object> properties = GetNext(isolate, lvl + 1);
3382 Handle<Object> elements = GetNext(isolate, lvl + 1);
3383 Handle<Object> length = GetNext(isolate, lvl + 1);
3386 object->set_length(*length);
3391 "[couldn't handle instance type %d]\n", map->instance_type());
3398 case SlotRef::DUPLICATE_OBJECT: {
3399 int object_index = slot.DuplicateObjectId();
3400 Handle<Object>
object = materialized_objects_[object_index];
3401 materialized_objects_.Add(
object);
3409 FATAL(
"We should never get here - unexpected deopt slot kind.");
3414 void SlotRefValueBuilder::Finish(Isolate* isolate) {
3416 ASSERT(slot_refs_.length() == current_slot_);
3418 if (materialized_objects_.length() > prev_materialized_count_) {
3421 Handle<FixedArray> array = isolate->factory()->NewFixedArray(
3422 materialized_objects_.length());
3423 for (
int i = 0; i < materialized_objects_.length(); i++) {
3424 array->set(i, *(materialized_objects_.at(i)));
3426 isolate->materialized_object_store()->Set(stack_frame_id_, array);
3432 int index = StackIdToIndex(fp);
3437 ASSERT(array->length() > index);
3445 int index = StackIdToIndex(fp);
3447 index = frame_fps_.length();
3452 array->set(index, *materialized_objects);
3457 int index = StackIdToIndex(fp);
3460 frame_fps_.
Remove(index);
3462 ASSERT(array->length() > index);
3463 for (
int i = index; i < frame_fps_.length(); i++) {
3464 array->set(i, array->get(i + 1));
3466 array->set(frame_fps_.length(), isolate()->heap()->undefined_value());
3470 int MaterializedObjectStore::StackIdToIndex(
Address fp) {
3471 for (
int i = 0; i < frame_fps_.length(); i++) {
3472 if (frame_fps_[i] == fp) {
3480 Handle<FixedArray> MaterializedObjectStore::GetStackEntries() {
3481 return Handle<FixedArray>(isolate()->heap()->materialized_objects());
3485 Handle<FixedArray> MaterializedObjectStore::EnsureStackEntries(
int length) {
3486 Handle<FixedArray> array = GetStackEntries();
3487 if (array->length() >= length) {
3491 int new_length = length > 10 ? length : 10;
3492 if (new_length < 2 * array->length()) {
3493 new_length = 2 * array->length();
3496 Handle<FixedArray> new_array =
3497 isolate()->factory()->NewFixedArray(new_length,
TENURED);
3498 for (
int i = 0; i < array->length(); i++) {
3499 new_array->set(i, array->get(i));
3501 for (
int i = array->length(); i < length; i++) {
3502 new_array->set(i, isolate()->heap()->undefined_value());
3504 isolate()->heap()->public_set_materialized_objects(*new_array);
3508 #ifdef ENABLE_DEBUGGER_SUPPORT
3510 DeoptimizedFrameInfo::DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
3512 bool has_arguments_adaptor,
3513 bool has_construct_stub) {
3514 FrameDescription* output_frame = deoptimizer->output_[frame_index];
3515 function_ = output_frame->GetFunction();
3516 has_construct_stub_ = has_construct_stub;
3517 expression_count_ = output_frame->GetExpressionCount();
3518 expression_stack_ =
new Object*[expression_count_];
3521 Code* code =
Code::cast(deoptimizer->isolate()->FindCodeObject(pc));
3524 for (
int i = 0; i < expression_count_; i++) {
3525 SetExpression(i, output_frame->GetExpression(i));
3528 if (has_arguments_adaptor) {
3529 output_frame = deoptimizer->output_[frame_index - 1];
3533 parameters_count_ = output_frame->ComputeParametersCount();
3534 parameters_ =
new Object*[parameters_count_];
3535 for (
int i = 0; i < parameters_count_; i++) {
3536 SetParameter(i, output_frame->GetParameter(i));
3541 DeoptimizedFrameInfo::~DeoptimizedFrameInfo() {
3542 delete[] expression_stack_;
3543 delete[] parameters_;
3547 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) {
3548 v->VisitPointer(BitCast<Object**>(&function_));
3549 v->VisitPointers(parameters_, parameters_ + parameters_count_);
3550 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_);
3553 #endif // ENABLE_DEBUGGER_SUPPORT
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
static const int kConstructorOffset
Code * builtin(Name name)
static DeoptimizationOutputData * cast(Object *obj)
static const int kBailoutTypesWithCodeEntry
static Object *& Object_at(Address addr)
static void EnsureCodeForDeoptimizationEntry(Isolate *isolate, BailoutType type, int max_entry_id)
Object * OptimizedCodeListHead()
void PrintF(const char *format,...)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf map
CodeTracer * GetCodeTracer()
void SetDeoptimizedCodeListHead(Object *head)
BailoutId AstId(int index)
static const int kFixedFrameSize
void SourceCodePrint(StringStream *accumulator, int max_length)
bool CommitArea(size_t requested)
static Smi * FromInt(int value)
#define LOG(isolate, Call)
unsigned GetOffsetFromSlotIndex(int slot_index)
void SetFrameSlot(unsigned offset, intptr_t value)
static void ComputeOutputFrames(Deoptimizer *deoptimizer)
static Handle< T > cast(Handle< S > that)
static Register fp_register()
kSerializedDataOffset Object
TypeImpl< ZoneTypeConfig > Type
DeoptimizerData(MemoryAllocator *allocator)
static const char * MessageFor(BailoutType type)
CodeStubInterfaceDescriptor * code_stub_interface_descriptor(int index)
#define ASSERT(condition)
static void DeoptimizeFunction(JSFunction *function)
Handle< JSFunction > function() const
int SourcePosition(Address pc)
static Context * cast(Object *context)
double GetDoubleRegister(unsigned n) const
intptr_t GetContext() const
void MaterializeHeapObjects(JavaScriptFrameIterator *it)
Handle< Object > NewNumber(double value, PretenureFlag pretenure=NOT_TENURED)
void SetFrameType(StackFrame::Type type)
static bool TraceEnabledFor(BailoutType deopt_type, StackFrame::Type frame_type)
Handle< JSObject > NewArgumentsObject(Handle< Object > callee, int length)
static Code * cast(Object *obj)
void set_emit_debug_code(bool value)
void PrintDeoptLocation(FILE *out, int bailout_id)
Object * FindCodeObject(Address a)
static Smi * cast(Object *object)
static const char * AllocationIndexToString(int index)
Object * DeoptimizedCodeListHead()
static Register constant_pool_pointer_register()
static const int kNumRegisters
void Free(MemoryChunk *chunk)
static void VisitAllOptimizedFunctions(Isolate *isolate, OptimizedFunctionVisitor *visitor)
SmartArrayPointer< char > ToCString(AllowNullsFlag allow_nulls, RobustnessFlag robustness_flag, int offset, int length, int *length_output=0)
int ComputeParametersCount()
JSFunction * GetFunction() const
Handle< Code > compiled_code() const
static void DeoptimizeGlobalObject(JSObject *object)
Handle< JSObject > NewJSObjectFromMap(Handle< Map > map, PretenureFlag pretenure=NOT_TENURED, bool allocate_properties=true, Handle< AllocationSite > allocation_site=Handle< AllocationSite >::null())
static int output_offset()
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_string(expose_natives_as
Isolate * isolate() const
DwVfpRegister DoubleRegister
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object size
virtual const char * NameOfCPURegister(int reg) const
static Register constant_pool_pointer_register()
static void MemCopy(void *dest, const void *src, size_t size)
Context * native_context()
static bool IsValid(intptr_t value)
static Address GetDeoptimizationEntry(Isolate *isolate, int id, BailoutType type, GetEntryMode mode=ENSURE_ENTRY_CODE)
Smi * PcAndState(int index)
void GetCode(CodeDesc *desc)
Object * GetPrototype(Isolate *isolate)
static int GetDeoptimizationId(Isolate *isolate, Address addr, BailoutType type)
static int32_t & int32_at(Address addr)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
void SetOptimizedCodeListHead(Object *head)
void SetRegister(unsigned n, intptr_t value)
static const int kCallerSPOffset
static const char * Kind2String(Kind kind)
static void DeoptimizeAll(Isolate *isolate)
Handle< FixedArray > NewFixedArray(int size, PretenureFlag pretenure=NOT_TENURED)
static int GetDeoptimizedCodeCount(Isolate *isolate)
SafepointEntry GetSafepointEntry(Address pc)
unsigned GetExpressionCount()
static const char * State2String(State state)
static int GetOutputInfo(DeoptimizationOutputData *data, BailoutId node_id, SharedFunctionInfo *shared)
static const int kFrameSize
DeoptimizerData * deoptimizer_data()
uint32_t GetFrameSize() const
#define ASSERT_LT(v1, v2)
static Handle< Object > FunctionGetArguments(Handle< JSFunction > object)
void PrintName(FILE *out=stdout)
static const int kFixedFrameSizeFromFp
intptr_t GetFrameSlot(unsigned offset)
static Register fp_register()
Handle< T > handle(T *t, Isolate *isolate)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function info
friend class DeoptimizedFrameInfo
Object * native_contexts_list()
static int ToAllocationIndex(DwVfpRegister reg)
static Deoptimizer * Grab(Isolate *isolate)
static const int kNotDeoptimizationEntry
void CopyBytes(uint8_t *target, uint8_t *source)
static Handle< T > null()
#define ASSERT_EQ(v1, v2)
friend class FrameDescription
MaterializedObjectStore * materialized_object_store()
StackFrame::Type GetFrameType() const
kInstanceClassNameOffset kNeedsAccessCheckBit kRemovePrototypeBit kIsExpressionBit kAllowLazyCompilation kUsesArguments formal_parameter_count
static Register context_register()
#define ASSERT_NE(v1, v2)
PerThreadAssertScopeDebugOnly< HEAP_ALLOCATION_ASSERT, false > DisallowHeapAllocation
static FixedArray * cast(Object *obj)
double GetDoubleFrameSlot(unsigned offset)
FrameDescription(uint32_t frame_size, JSFunction *function)
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
static uint32_t & uint32_at(Address addr)
static size_t GetMaxDeoptTableSize()
void set_marked_for_deoptimization(bool flag)
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric literals(0o77, 0b11)") DEFINE_bool(harmony_strings
int ConvertJSFrameIndexToFrameIndex(int jsframe_index)
static unsigned decode(uint32_tvalue)
static Representation Tagged()
static const int kFrameSize
intptr_t GetRegister(unsigned n) const
static void DeoptimizeMarkedCode(Isolate *isolate)
static GlobalObject * cast(Object *obj)
SmartArrayPointer< const char > ToCString() const
static Handle< Map > GeneralizeAllFieldRepresentations(Handle< Map > map, Representation new_representation)
static FixedArrayBase * cast(Object *object)
int jsframe_count() const
Handle< FixedArray > Get(Address fp)
static const int kMaxValue
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print statistics of the maximum memory committed for the heap in name
static intptr_t CommitPageSize()
#define TRANSLATION_OPCODE_LIST(V)
bool has_adapted_arguments() const
JSFunction * function() const
static Register context_register()
Handle< JSArray > NewJSArray(ElementsKind elements_kind, int length, int capacity, ArrayStorageAllocationMode mode=INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE, PretenureFlag pretenure=NOT_TENURED)
void Set(Address fp, Handle< FixedArray > materialized_objects)
static Deoptimizer * New(JSFunction *function, BailoutType type, unsigned bailout_id, Address from, int fp_to_sp_delta, Isolate *isolate)
static int input_offset()
intptr_t GetConstantPool() const
Object * GetExpression(int index)
Object * GetParameter(int index)
static JSFunction * cast(Object *obj)