23 #
if defined(__native_client__)
35 : allocator_(allocator),
36 deoptimized_frame_info_(
NULL),
65 while (!element->IsUndefined()) {
66 Code* code = Code::cast(element);
67 CHECK(code->
kind() == Code::OPTIMIZED_FUNCTION);
68 if (code->
contains(addr))
return code;
69 element = code->next_code_link();
106 commit_page_size) + 1;
107 return static_cast<size_t>(commit_page_size * page_count);
121 if (jsframe_index == 0)
return 0;
124 while (jsframe_index >= 0) {
132 return frame_index - 1;
140 CHECK(frame->is_optimized());
145 Code* code = frame->LookupCode();
150 int deoptimization_index = safepoint_entry.deoptimization_index();
151 CHECK_NE(deoptimization_index, Safepoint::kNoDeoptimizationIndex);
156 unsigned fp_to_sp_delta = (stack_slots *
kPointerSize) +
162 deoptimization_index,
166 Address tos = frame->fp() - fp_to_sp_delta;
179 bool has_arguments_adaptor =
184 int construct_offset = has_arguments_adaptor ? 2 : 1;
185 bool has_construct_stub =
186 frame_index >= construct_offset &&
188 StackFrame::CONSTRUCT;
192 has_arguments_adaptor,
199 has_arguments_adaptor ? (frame_index - 1) : frame_index];
215 parameters_top, parameters_size, expressions_top, expressions_size, info);
236 generator.Generate();
246 visitor->EnterContext(context);
252 while (!element->IsUndefined()) {
253 JSFunction*
function = JSFunction::cast(element);
254 Object* next =
function->next_function_link();
255 if (
function->code()->kind() != Code::OPTIMIZED_FUNCTION ||
256 (visitor->VisitFunction(
function),
257 function->code()->kind() != Code::OPTIMIZED_FUNCTION)) {
262 prev->set_next_function_link(next);
270 function->set_next_function_link(context->
GetHeap()->undefined_value());
280 visitor->LeaveContext(context);
291 while (!context->IsUndefined()) {
308 virtual void EnterContext(
Context* context) { }
309 virtual void LeaveContext(
Context* context) { }
310 virtual void VisitFunction(
JSFunction*
function) {
311 Code* code =
function->code();
316 function->set_code(shared->code());
318 if (FLAG_trace_deopt) {
320 PrintF(scope.file(),
"[deoptimizer unlinked: ");
321 function->PrintName(scope.file());
323 " / %" V8PRIxPTR "]\n",
reinterpret_cast<intptr_t
>(
function));
329 SelectedCodeUnlinker unlinker;
334 Code* topmost_optimized_code =
NULL;
335 bool safe_to_deopt_topmost_optimized_code =
false;
342 if (type == StackFrame::OPTIMIZED) {
343 Code* code = it.frame()->LookupCode();
344 if (FLAG_trace_deopt) {
348 PrintF(scope.file(),
"[deoptimizer found activation of function: ");
349 function->PrintName(scope.file());
351 " / %" V8PRIxPTR "]\n",
reinterpret_cast<intptr_t
>(
function));
354 int deopt_index = safepoint.deoptimization_index();
356 bool turbofanned = code->
is_turbofanned() && !FLAG_turbo_deoptimization;
358 deopt_index != Safepoint::kNoDeoptimizationIndex || turbofanned;
359 CHECK(topmost_optimized_code ==
NULL || safe_to_deopt || turbofanned);
360 if (topmost_optimized_code ==
NULL) {
361 topmost_optimized_code = code;
362 safe_to_deopt_topmost_optimized_code = safe_to_deopt;
376 while (!element->IsUndefined()) {
377 Code* code = Code::cast(element);
379 Object* next = code->next_code_link();
384 codes.
Add(code, &zone);
388 prev->set_next_code_link(next);
409 for (
int i = 0;
i < codes.length();
i++) {
411 if (codes[
i] == topmost_optimized_code) {
412 DCHECK(safe_to_deopt_topmost_optimized_code);
419 DeoptimizationInputData::cast(codes[
i]->deoptimization_data());
421 SharedFunctionInfo::cast(deopt_data->SharedFunctionInfo());
425 if (!codes[
i]->is_turbofanned() || FLAG_turbo_deoptimization) {
438 if (FLAG_trace_deopt) {
440 PrintF(scope.file(),
"[deoptimize all code in all contexts]\n");
445 while (!context->IsUndefined()) {
455 if (FLAG_trace_deopt) {
457 PrintF(scope.file(),
"[deoptimize marked code in all contexts]\n");
462 while (!context->IsUndefined()) {
471 if (FLAG_trace_deopt) {
473 PrintF(scope.file(),
"[deoptimize global object @ 0x%08" V8PRIxPTR "]\n",
474 reinterpret_cast<intptr_t
>(
object));
476 if (object->IsJSGlobalProxy()) {
484 }
else if (object->IsGlobalObject()) {
494 while (!element->IsUndefined()) {
495 Code* code = Code::cast(element);
498 element = code->next_code_link();
504 Code* code =
function->code();
505 if (code->
kind() == Code::OPTIMIZED_FUNCTION) {
522 switch (deopt_type) {
528 ? FLAG_trace_stub_failures
531 FATAL(
"Unsupported deopt type");
538 case EAGER:
return "eager";
539 case SOFT:
return "soft";
540 case LAZY:
return "lazy";
543 FATAL(
"Unsupported deopt type");
554 Code* optimized_code)
557 bailout_id_(bailout_id),
560 fp_to_sp_delta_(fp_to_sp_delta),
561 has_alignment_padding_(0),
566 deferred_objects_tagged_values_(0),
567 deferred_objects_double_values_(0),
568 deferred_objects_(0),
569 deferred_heap_numbers_(0),
570 jsframe_functions_(0),
571 jsframe_has_adapted_arguments_(0),
572 materialized_values_(
NULL),
573 materialized_objects_(
NULL),
574 materialization_value_index_(0),
575 materialization_object_index_(0),
584 function->shared()->increment_deopt_count();
589 int opt_count =
function->shared()->opt_count();
590 if (opt_count > 0) opt_count--;
591 function->shared()->set_opt_count(opt_count);
605 : StackFrame::JAVA_SCRIPT;
609 CHECK(AllowHeapAllocation::IsAllowed());
619 Code* optimized_code) {
631 return optimized_code;
633 FATAL(
"Could not find code for optimized function");
664 CHECK(!AllowHeapAllocation::IsAllowed());
665 CHECK(disallow_heap_allocation_ !=
NULL);
666 delete disallow_heap_allocation_;
667 disallow_heap_allocation_ =
NULL;
714 for (
int i = 0;
i < length;
i++) {
715 if (data->
AstId(
i) ==
id) {
720 os <<
"[couldn't find pc offset for node=" <<
id.ToInt() <<
"]\n"
724 FATAL(
"unable to find pc offset during deoptimization");
733 while (!context->IsUndefined()) {
736 while (!element->IsUndefined()) {
737 Code* code = Code::cast(element);
738 DCHECK(code->
kind() == Code::OPTIMIZED_FUNCTION);
740 element = code->next_code_link();
752 if (FLAG_log_timer_events &&
756 base::ElapsedTimer timer;
761 DeoptimizationInputData::cast(
compiled_code_->deoptimization_data());
766 "[deoptimizing (DEOPT %s): begin 0x%08" V8PRIxPTR " ",
771 " (opt #%d) @%d, FP to SP delta: %d]\n",
772 input_data->OptimizationId()->value(),
782 ByteArray* translations = input_data->TranslationByteArray();
783 unsigned translation_index =
784 input_data->TranslationIndex(
bailout_id_)->value();
787 TranslationIterator iterator(translations, translation_index);
790 DCHECK(Translation::BEGIN == opcode);
794 int count = iterator.Next();
798 for (
int i = 0;
i < count; ++
i) {
809 for (
int i = 0;
i < count; ++
i) {
818 case Translation::ARGUMENTS_ADAPTOR_FRAME:
821 case Translation::CONSTRUCT_STUB_FRAME:
824 case Translation::GETTER_STUB_FRAME:
827 case Translation::SETTER_STUB_FRAME:
830 case Translation::COMPILED_STUB_FRAME:
833 case Translation::BEGIN:
835 case Translation::INT32_REGISTER:
836 case Translation::UINT32_REGISTER:
837 case Translation::DOUBLE_REGISTER:
838 case Translation::STACK_SLOT:
839 case Translation::INT32_STACK_SLOT:
840 case Translation::UINT32_STACK_SLOT:
841 case Translation::DOUBLE_STACK_SLOT:
842 case Translation::LITERAL:
843 case Translation::ARGUMENTS_OBJECT:
845 FATAL(
"Unsupported translation");
852 double ms = timer.Elapsed().InMillisecondsF();
856 "[deoptimizing (%s): end 0x%08" V8PRIxPTR " ",
858 reinterpret_cast<intptr_t
>(
function));
861 " @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s,"
879 if (frame_index != 0) {
882 int closure_id = iterator->Next();
884 CHECK_EQ(Translation::kSelfLiteralId, closure_id);
887 unsigned height = iterator->Next() - 1;
893 " => node=%d, height=%d\n", node_id.
ToInt(), height_in_bytes);
900 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
907 bool is_bottommost = (0 == frame_index);
911 output_[frame_index] = output_frame;
918 intptr_t top_address;
933 top_address =
output_[frame_index - 1]->
GetTop() - output_frame_size;
935 output_frame->
SetTop(top_address);
938 int parameter_count =
function->shared()->formal_parameter_count() + 1;
941 for (
int i = 0;
i < parameter_count; ++
i) {
966 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
986 output_frame->
SetFp(fp_value);
990 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
997 if (FLAG_enable_ool_constant_pool) {
1003 if (is_bottommost) {
1027 reinterpret_cast<intptr_t
>(
isolate_->
heap()->arguments_marker()));
1029 reinterpret_cast<intptr_t
>(
isolate_->
heap()->undefined_value())) {
1033 if (is_bottommost) {
1036 value =
reinterpret_cast<intptr_t
>(
function->context());
1044 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1052 value =
reinterpret_cast<intptr_t
>(
function);
1059 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1065 for (
unsigned i = 0;
i < height; ++
i) {
1072 Code* non_optimized_code =
function->shared()->code();
1073 FixedArray* raw_data = non_optimized_code->deoptimization_data();
1078 intptr_t pc_value =
reinterpret_cast<intptr_t
>(start + pc_offset);
1079 output_frame->
SetPc(pc_value);
1082 if (FLAG_enable_ool_constant_pool) {
1083 intptr_t constant_pool_value =
1084 reinterpret_cast<intptr_t
>(non_optimized_code->
constant_pool());
1089 output_frame->
SetRegister(constant_pool_reg.
code(), constant_pool_value);
1100 Code* continuation = builtins->
builtin(Builtins::kNotifyDeoptimized);
1102 continuation = builtins->
builtin(Builtins::kNotifyLazyDeoptimized);
1104 continuation = builtins->
builtin(Builtins::kNotifySoftDeoptimized);
1109 reinterpret_cast<intptr_t
>(continuation->
entry()));
1117 unsigned height = iterator->Next();
1121 " translating arguments adaptor => height=%d\n", height_in_bytes);
1125 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1135 output_[frame_index] = output_frame;
1139 intptr_t top_address;
1140 top_address =
output_[frame_index - 1]->
GetTop() - output_frame_size;
1141 output_frame->
SetTop(top_address);
1144 int parameter_count = height;
1146 for (
int i = 0;
i < parameter_count; ++
i) {
1153 intptr_t callers_pc =
output_[frame_index - 1]->
GetPc();
1157 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1167 output_frame->
SetFp(fp_value);
1170 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1175 if (FLAG_enable_ool_constant_pool) {
1189 intptr_t context =
reinterpret_cast<intptr_t
>(
1194 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1195 V8PRIxPTR " ; context (adaptor sentinel)\n",
1201 value =
reinterpret_cast<intptr_t
>(
function);
1205 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1212 value =
reinterpret_cast<intptr_t
>(
Smi::FromInt(height - 1));
1216 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1224 Code* adaptor_trampoline =
1225 builtins->
builtin(Builtins::kArgumentsAdaptorTrampoline);
1226 intptr_t pc_value =
reinterpret_cast<intptr_t
>(
1228 isolate_->
heap()->arguments_adaptor_deopt_pc_offset()->value());
1229 output_frame->
SetPc(pc_value);
1230 if (FLAG_enable_ool_constant_pool) {
1231 intptr_t constant_pool_value =
1232 reinterpret_cast<intptr_t
>(adaptor_trampoline->
constant_pool());
1241 Code* construct_stub = builtins->
builtin(Builtins::kJSConstructStubGeneric);
1243 unsigned height = iterator->Next();
1247 " translating construct stub => height=%d\n", height_in_bytes);
1251 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1261 output_[frame_index] = output_frame;
1265 intptr_t top_address;
1266 top_address =
output_[frame_index - 1]->
GetTop() - output_frame_size;
1267 output_frame->
SetTop(top_address);
1270 int parameter_count = height;
1272 for (
int i = 0;
i < parameter_count; ++
i) {
1287 intptr_t callers_pc =
output_[frame_index - 1]->
GetPc();
1291 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1301 output_frame->
SetFp(fp_value);
1304 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1309 if (FLAG_enable_ool_constant_pool) {
1316 V8PRIxPTR " ; caller's constant pool\n",
1327 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1334 value =
reinterpret_cast<intptr_t
>(
Smi::FromInt(StackFrame::CONSTRUCT));
1338 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1339 V8PRIxPTR " ; function (construct sentinel)\n",
1345 value =
reinterpret_cast<intptr_t
>(construct_stub);
1349 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1356 value =
reinterpret_cast<intptr_t
>(
Smi::FromInt(height - 1));
1360 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1369 value =
reinterpret_cast<intptr_t
>(
function);
1373 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1386 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1393 intptr_t
pc =
reinterpret_cast<intptr_t
>(
1395 isolate_->
heap()->construct_stub_deopt_pc_offset()->value());
1397 if (FLAG_enable_ool_constant_pool) {
1398 intptr_t constant_pool_value =
1399 reinterpret_cast<intptr_t
>(construct_stub->
constant_pool());
1407 bool is_setter_stub_frame) {
1412 unsigned height = 0;
1414 const char* kind = is_setter_stub_frame ?
"setter" :
"getter";
1417 " translating %s stub => height=%u\n", kind, height_in_bytes);
1425 unsigned fixed_frame_entries =
1427 (is_setter_stub_frame ? 1 : 0);
1428 unsigned fixed_frame_size = fixed_frame_entries *
kPointerSize;
1429 unsigned output_frame_size = height_in_bytes + fixed_frame_size;
1439 output_[frame_index] = output_frame;
1443 intptr_t top_address =
output_[frame_index - 1]->
GetTop() - output_frame_size;
1444 output_frame->
SetTop(top_address);
1450 intptr_t callers_pc =
output_[frame_index - 1]->
GetPc();
1464 output_frame->
SetFp(fp_value);
1472 if (FLAG_enable_ool_constant_pool) {
1479 V8PRIxPTR " ; caller's constant pool\n",
1502 " ; function (%s sentinel)\n",
1509 Builtins::kStoreIC_Setter_ForDeopt :
1510 Builtins::kLoadIC_Getter_ForDeopt;
1512 value =
reinterpret_cast<intptr_t
>(accessor_stub);
1524 if (is_setter_stub_frame) {
1533 Smi* offset = is_setter_stub_frame ?
1536 intptr_t
pc =
reinterpret_cast<intptr_t
>(
1539 if (FLAG_enable_ool_constant_pool) {
1540 intptr_t constant_pool_value =
1596 int output_frame_size = height_in_bytes + fixed_frame_size;
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);
1609 output_[frame_index] = output_frame;
1617 output_frame->
SetTop(top_address);
1621 unsigned output_frame_offset = output_frame_size -
kFPOnStackSize;
1623 output_frame->
SetCallerPc(output_frame_offset, value);
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);
1638 output_frame->
SetFp(frame_ptr);
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) {
1654 V8PRIxPTR " ; caller's constant_pool\n",
1655 top_address + output_frame_offset, output_frame_offset, value);
1665 output_frame->
SetFrameSlot(output_frame_offset, value);
1666 CHECK(
reinterpret_cast<Object*
>(value)->IsContext());
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);
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;
1691 int args_arguments_offset = output_frame_offset;
1692 intptr_t the_hole =
reinterpret_cast<intptr_t
>(
1694 if (arg_count_known) {
1701 output_frame->
SetFrameSlot(args_arguments_offset, value);
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);
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);
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 < param_count; ++
i) {
1740 arguments_length_offset = output_frame_offset;
1746 if (!arg_count_known) {
1747 CHECK_GE(arguments_length_offset, 0);
1751 Smi* smi_caller_arg_count =
reinterpret_cast<Smi*
>(
1753 caller_arg_count = smi_caller_arg_count->
value();
1754 output_frame->
SetFrameSlot(length_frame_offset, caller_arg_count);
1757 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1759 top_address + length_frame_offset, length_frame_offset,
1764 output_frame->
SetFrameSlot(args_arguments_offset, value);
1767 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
1769 top_address + args_arguments_offset, args_arguments_offset,
1784 function_mode).FindCodeInCache(&trampoline);
1786 output_frame->
SetPc(
reinterpret_cast<intptr_t
>(
1788 if (FLAG_enable_ool_constant_pool) {
1791 intptr_t constant_pool_value =
1794 output_frame->
SetRegister(constant_pool_reg.
code(), constant_pool_value);
1797 Code* notify_failure =
1800 reinterpret_cast<intptr_t
>(notify_failure->
entry()));
1807 const int length = desc.object_length();
1809 if (desc.duplicate_object() >= 0) {
1811 object_index = desc.duplicate_object();
1822 for (
int i = 0;
i < length; ++
i) {
1825 }
else if (desc.is_arguments()) {
1833 arguments->set_elements(*array);
1835 for (
int i = 0;
i < length; ++
i) {
1837 array->set(
i, *value);
1845 switch (
map->instance_type()) {
1872 object->set_properties(FixedArray::cast(*properties));
1873 object->set_elements(FixedArrayBase::cast(*elements));
1874 for (
int i = 0;
i < length - 3; ++
i) {
1876 FieldIndex index = FieldIndex::ForPropertyIndex(object->map(),
i);
1877 object->FastPropertyAtPut(index, *value);
1893 object->set_properties(FixedArray::cast(*properties));
1894 object->set_elements(FixedArrayBase::cast(*elements));
1895 object->set_length(*length);
1900 "[couldn't handle instance type %d]\n",
map->instance_type());
1901 FATAL(
"Unsupported instance type");
1912 if (value->IsMutableHeapNumber()) {
1913 HeapNumber::cast(*value)->set_map(
isolate_->
heap()->heap_number_map());
1932 for (
int frame_index = 0; frame_index <
jsframe_count(); ++frame_index) {
1933 if (frame_index != 0) it->Advance();
1956 "Materialized a new heap number %p [%e] in slot %p\n",
1957 reinterpret_cast<void*
>(*num),
1966 HeapNumberMaterializationDescriptor<int> d =
1971 "Materialized a new heap number %p [%e] for object at %d\n",
1972 reinterpret_cast<void*
>(*num),
1976 DCHECK(values.
at(d.destination())->IsTheHole());
1977 values.
Set(d.destination(), num);
1991 ObjectMaterializationDescriptor descriptor =
1998 if (descriptor.slot_address() !=
NULL) {
2002 if (descriptor.is_arguments()) {
2004 "Materialized %sarguments object of length %d for %p: ",
2007 reinterpret_cast<void*
>(descriptor.slot_address()));
2010 "Materialized captured object of size %d for %p: ",
2012 reinterpret_cast<void*
>(descriptor.slot_address()));
2036 Address parameters_bottom = parameters_top + parameters_size;
2037 Address expressions_bottom = expressions_top + expressions_size;
2043 Address slot = d.destination();
2044 if (parameters_top <= slot && slot < parameters_bottom) {
2048 static_cast<int>(slot - parameters_top) /
kPointerSize;
2052 "Materializing a new heap number %p [%e] in slot %p"
2053 "for parameter slot #%d\n",
2054 reinterpret_cast<void*
>(*num),
2061 }
else if (expressions_top <= slot && slot < expressions_bottom) {
2065 static_cast<int>(slot - expressions_top) /
kPointerSize;
2069 "Materializing a new heap number %p [%e] in slot %p"
2070 "for expression slot #%d\n",
2071 reinterpret_cast<void*
>(*num),
2088 return "heap number";
2097 case Translation::BEGIN:
2099 case Translation::ARGUMENTS_ADAPTOR_FRAME:
2100 case Translation::CONSTRUCT_STUB_FRAME:
2101 case Translation::GETTER_STUB_FRAME:
2102 case Translation::SETTER_STUB_FRAME:
2103 case Translation::COMPILED_STUB_FRAME: {
2104 FATAL(
"Unexpected frame start translation opcode");
2109 case Translation::INT32_REGISTER:
2110 case Translation::UINT32_REGISTER:
2111 case Translation::DOUBLE_REGISTER:
2112 case Translation::STACK_SLOT:
2113 case Translation::INT32_STACK_SLOT:
2114 case Translation::UINT32_STACK_SLOT:
2115 case Translation::DOUBLE_STACK_SLOT:
2116 case Translation::LITERAL: {
2118 iterator->Skip(Translation::NumberOfOperandsFor(opcode));
2122 case Translation::DUPLICATED_OBJECT: {
2123 int object_index = iterator->Next();
2127 " ; duplicate of object #%d\n", object_index);
2133 case Translation::ARGUMENTS_OBJECT:
2134 case Translation::CAPTURED_OBJECT: {
2135 int length = iterator->Next();
2136 bool is_args = opcode == Translation::ARGUMENTS_OBJECT;
2140 " ; object (length = %d, is_args = %d)\n", length, is_args);
2148 for (
int i = 0;
i < length;
i++) {
2155 FATAL(
"Unexpected translation opcode");
2169 case Translation::BEGIN:
2171 case Translation::ARGUMENTS_ADAPTOR_FRAME:
2172 case Translation::CONSTRUCT_STUB_FRAME:
2173 case Translation::GETTER_STUB_FRAME:
2174 case Translation::SETTER_STUB_FRAME:
2175 case Translation::COMPILED_STUB_FRAME:
2176 FATAL(
"Unexpected frame start translation opcode");
2180 int input_reg = iterator->Next();
2184 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2185 reinterpret_cast<intptr_t
>(object_slot),
2188 "0x%08" V8PRIxPTR " ; %s ", input_value,
2190 reinterpret_cast<Object*
>(input_value)->ShortPrint(
2199 case Translation::INT32_REGISTER: {
2200 int input_reg = iterator->Next();
2205 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2206 reinterpret_cast<intptr_t
>(object_slot),
2214 intptr_t tagged_value =
2215 reinterpret_cast<intptr_t
>(
Smi::FromInt(
static_cast<int>(value)));
2218 double double_value =
static_cast<double>(
static_cast<int32_t>(value));
2224 case Translation::UINT32_REGISTER: {
2225 int input_reg = iterator->Next();
2230 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2231 reinterpret_cast<intptr_t
>(object_slot),
2234 "%" V8PRIdPTR " ; uint %s (%s)\n", value,
2239 intptr_t tagged_value =
2240 reinterpret_cast<intptr_t
>(
Smi::FromInt(
static_cast<int>(value)));
2243 double double_value =
static_cast<double>(
static_cast<uint32_t>(value));
2249 case Translation::DOUBLE_REGISTER: {
2250 int input_reg = iterator->Next();
2254 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2255 reinterpret_cast<intptr_t
>(object_slot),
2265 case Translation::STACK_SLOT: {
2266 int input_slot_index = iterator->Next();
2271 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2272 reinterpret_cast<intptr_t
>(object_slot),
2276 reinterpret_cast<Object*
>(input_value)->ShortPrint(
2285 case Translation::INT32_STACK_SLOT: {
2286 int input_slot_index = iterator->Next();
2292 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2293 reinterpret_cast<intptr_t
>(object_slot),
2300 intptr_t tagged_value =
2301 reinterpret_cast<intptr_t
>(
Smi::FromInt(
static_cast<int>(value)));
2304 double double_value =
static_cast<double>(
static_cast<int32_t>(value));
2310 case Translation::UINT32_STACK_SLOT: {
2311 int input_slot_index = iterator->Next();
2318 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2319 reinterpret_cast<intptr_t
>(object_slot),
2322 "%" V8PRIdPTR " ; [sp + %d] (uint %s)\n",
2326 intptr_t tagged_value =
2327 reinterpret_cast<intptr_t
>(
Smi::FromInt(
static_cast<int>(value)));
2330 double double_value =
static_cast<double>(
static_cast<uint32_t>(value));
2336 case Translation::DOUBLE_STACK_SLOT: {
2337 int input_slot_index = iterator->Next();
2342 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2343 reinterpret_cast<intptr_t
>(object_slot),
2352 case Translation::LITERAL: {
2356 " object @0x%08" V8PRIxPTR ": [field #%d] <- ",
2357 reinterpret_cast<intptr_t
>(object_slot),
2363 intptr_t value =
reinterpret_cast<intptr_t
>(literal);
2368 case Translation::DUPLICATED_OBJECT: {
2369 int object_index = iterator->Next();
2372 " nested @0x%08" V8PRIxPTR ": [field #%d] <- ",
2373 reinterpret_cast<intptr_t
>(object_slot),
2377 " ; duplicate of object #%d\n", object_index);
2381 intptr_t value =
reinterpret_cast<intptr_t
>(
2388 case Translation::ARGUMENTS_OBJECT:
2389 case Translation::CAPTURED_OBJECT: {
2390 int length = iterator->Next();
2391 bool is_args = opcode == Translation::ARGUMENTS_OBJECT;
2394 " nested @0x%08" V8PRIxPTR ": [field #%d] <- ",
2395 reinterpret_cast<intptr_t
>(object_slot),
2399 " ; object (length = %d, is_args = %d)\n", length, is_args);
2403 intptr_t value =
reinterpret_cast<intptr_t
>(
2410 for (
int i = 0;
i < length;
i++) {
2417 FATAL(
"Unexpected translation opcode");
2423 unsigned output_offset) {
2426 const intptr_t kPlaceholder =
reinterpret_cast<intptr_t
>(
Smi::FromInt(0));
2432 case Translation::BEGIN:
2434 case Translation::ARGUMENTS_ADAPTOR_FRAME:
2435 case Translation::CONSTRUCT_STUB_FRAME:
2436 case Translation::GETTER_STUB_FRAME:
2437 case Translation::SETTER_STUB_FRAME:
2438 case Translation::COMPILED_STUB_FRAME:
2439 FATAL(
"Unexpected translation opcode");
2443 int input_reg = iterator->Next();
2453 reinterpret_cast<Object*
>(input_value)->ShortPrint(
2461 case Translation::INT32_REGISTER: {
2462 int input_reg = iterator->Next();
2476 intptr_t tagged_value =
2477 reinterpret_cast<intptr_t
>(
Smi::FromInt(
static_cast<int>(value)));
2483 static_cast<double>(
static_cast<int32_t>(value)));
2489 case Translation::UINT32_REGISTER: {
2490 int input_reg = iterator->Next();
2497 " ; uint %s (%s)\n",
2505 intptr_t tagged_value =
2506 reinterpret_cast<intptr_t
>(
Smi::FromInt(
static_cast<int>(value)));
2512 static_cast<double>(
static_cast<uint32_t>(value)));
2518 case Translation::DOUBLE_REGISTER: {
2519 int input_reg = iterator->Next();
2523 " 0x%08" V8PRIxPTR ": [top + %d] <- %e ; %s\n",
2536 case Translation::STACK_SLOT: {
2537 int input_slot_index = iterator->Next();
2545 "[top + %d] <- 0x%08" V8PRIxPTR " ; [sp + %d] ",
2549 reinterpret_cast<Object*
>(input_value)->ShortPrint(
2557 case Translation::INT32_STACK_SLOT: {
2558 int input_slot_index = iterator->Next();
2567 "[top + %d] <- %" V8PRIdPTR " ; [sp + %d] (%s)\n",
2574 intptr_t tagged_value =
2575 reinterpret_cast<intptr_t
>(
Smi::FromInt(
static_cast<int>(value)));
2581 static_cast<double>(
static_cast<int32_t>(value)));
2587 case Translation::UINT32_STACK_SLOT: {
2588 int input_slot_index = iterator->Next();
2598 "[top + %d] <- %" V8PRIuPTR " ; [sp + %d] (uint32 %s)\n",
2605 intptr_t tagged_value =
2606 reinterpret_cast<intptr_t
>(
Smi::FromInt(
static_cast<int>(value)));
2612 static_cast<double>(
static_cast<uint32_t>(value)));
2618 case Translation::DOUBLE_STACK_SLOT: {
2619 int input_slot_index = iterator->Next();
2624 " 0x%08" V8PRIxPTR ": [top + %d] <- %e ; [sp + %d]\n",
2637 case Translation::LITERAL: {
2647 intptr_t value =
reinterpret_cast<intptr_t
>(literal);
2652 case Translation::DUPLICATED_OBJECT: {
2653 int object_index = iterator->Next();
2661 " ; duplicate of object #%d\n", object_index);
2665 intptr_t value =
reinterpret_cast<intptr_t
>(
2673 case Translation::ARGUMENTS_OBJECT:
2674 case Translation::CAPTURED_OBJECT: {
2675 int length = iterator->Next();
2676 bool is_args = opcode == Translation::ARGUMENTS_OBJECT;
2684 " ; object (length = %d, is_args = %d)\n", length, is_args);
2688 intptr_t value =
reinterpret_cast<intptr_t
>(
2696 for (
int i = 0;
i < length;
i++) {
2735 unsigned arguments =
function->shared()->formal_parameter_count() + 1;
2743 unsigned height = data->ArgumentsStackHeight(
bailout_id_)->value();
2757 ObjectMaterializationDescriptor object_desc(
2764 ObjectMaterializationDescriptor object_desc(
2777 HeapNumberMaterializationDescriptor<int> value_desc(
2784 HeapNumberMaterializationDescriptor<Address> value_desc(
2785 reinterpret_cast<Address>(slot_address), value);
2800 if (max_entry_id < entry_count)
return;
2802 while (max_entry_id >= entry_count) entry_count *= 2;
2810 DCHECK(!RelocInfo::RequiresRelocation(desc));
2826 : frame_size_(frame_size),
2827 function_(function),
2831 context_(kZapUint32),
2832 constant_pool_(kZapUint32) {
2842 for (
unsigned o = 0; o < frame_size; o +=
kPointerSize) {
2855 if (slot_index >= 0) {
2871 case StackFrame::JAVA_SCRIPT:
2872 return function_->shared()->formal_parameter_count();
2881 FATAL(
"Unexpected stack frame type");
2910 void TranslationBuffer::Add(
int32_t value,
Zone* zone) {
2912 bool is_negative = (value < 0);
2913 uint32_t bits = ((is_negative ? -value : value) << 1) |
2914 static_cast<int32_t>(is_negative);
2919 contents_.Add(((bits << 1) & 0xFF) | (next != 0), zone);
2921 }
while (bits != 0);
2925 int32_t TranslationIterator::Next() {
2929 for (
int i = 0;
true;
i += 7) {
2931 uint8_t next = buffer_->get(index_++);
2932 bits |= (next >> 1) <<
i;
2933 if ((next & 1) == 0)
break;
2936 bool is_negative = (bits & 1) == 1;
2938 return is_negative ? -result : result;
2942 Handle<ByteArray> TranslationBuffer::CreateByteArray(Factory* factory) {
2943 int length = contents_.length();
2944 Handle<ByteArray> result = factory->NewByteArray(length,
TENURED);
2945 MemCopy(result->GetDataStartAddress(), contents_.ToVector().start(), length);
2950 void Translation::BeginConstructStubFrame(
int literal_id,
unsigned height) {
2951 buffer_->Add(CONSTRUCT_STUB_FRAME, zone());
2952 buffer_->Add(literal_id, zone());
2953 buffer_->Add(height, zone());
2957 void Translation::BeginGetterStubFrame(
int literal_id) {
2958 buffer_->Add(GETTER_STUB_FRAME, zone());
2959 buffer_->Add(literal_id, zone());
2963 void Translation::BeginSetterStubFrame(
int literal_id) {
2964 buffer_->Add(SETTER_STUB_FRAME, zone());
2965 buffer_->Add(literal_id, zone());
2969 void Translation::BeginArgumentsAdaptorFrame(
int literal_id,
unsigned height) {
2970 buffer_->Add(ARGUMENTS_ADAPTOR_FRAME, zone());
2971 buffer_->Add(literal_id, zone());
2972 buffer_->Add(height, zone());
2976 void Translation::BeginJSFrame(BailoutId node_id,
2980 buffer_->Add(node_id.ToInt(), zone());
2981 buffer_->Add(literal_id, zone());
2982 buffer_->Add(height, zone());
2986 void Translation::BeginCompiledStubFrame() {
2987 buffer_->Add(COMPILED_STUB_FRAME, zone());
2991 void Translation::BeginArgumentsObject(
int args_length) {
2992 buffer_->Add(ARGUMENTS_OBJECT, zone());
2993 buffer_->Add(args_length, zone());
2997 void Translation::BeginCapturedObject(
int length) {
2998 buffer_->Add(CAPTURED_OBJECT, zone());
2999 buffer_->Add(length, zone());
3003 void Translation::DuplicateObject(
int object_index) {
3004 buffer_->Add(DUPLICATED_OBJECT, zone());
3005 buffer_->Add(object_index, zone());
3009 void Translation::StoreRegister(Register reg) {
3011 buffer_->Add(reg.code(), zone());
3015 void Translation::StoreInt32Register(Register reg) {
3016 buffer_->Add(INT32_REGISTER, zone());
3017 buffer_->Add(reg.code(), zone());
3021 void Translation::StoreUint32Register(Register reg) {
3022 buffer_->Add(UINT32_REGISTER, zone());
3023 buffer_->Add(reg.code(), zone());
3028 buffer_->Add(DOUBLE_REGISTER, zone());
3033 void Translation::StoreStackSlot(
int index) {
3034 buffer_->Add(STACK_SLOT, zone());
3035 buffer_->Add(index, zone());
3039 void Translation::StoreInt32StackSlot(
int index) {
3040 buffer_->Add(INT32_STACK_SLOT, zone());
3041 buffer_->Add(index, zone());
3045 void Translation::StoreUint32StackSlot(
int index) {
3046 buffer_->Add(UINT32_STACK_SLOT, zone());
3047 buffer_->Add(index, zone());
3051 void Translation::StoreDoubleStackSlot(
int index) {
3052 buffer_->Add(DOUBLE_STACK_SLOT, zone());
3053 buffer_->Add(index, zone());
3057 void Translation::StoreLiteral(
int literal_id) {
3058 buffer_->Add(LITERAL, zone());
3059 buffer_->Add(literal_id, zone());
3063 void Translation::StoreArgumentsObject(
bool args_known,
3066 buffer_->Add(ARGUMENTS_OBJECT, zone());
3067 buffer_->Add(args_known, zone());
3068 buffer_->Add(args_index, zone());
3069 buffer_->Add(args_length, zone());
3073 int Translation::NumberOfOperandsFor(
Opcode opcode) {
3075 case GETTER_STUB_FRAME:
3076 case SETTER_STUB_FRAME:
3077 case DUPLICATED_OBJECT:
3078 case ARGUMENTS_OBJECT:
3079 case CAPTURED_OBJECT:
3081 case INT32_REGISTER:
3082 case UINT32_REGISTER:
3083 case DOUBLE_REGISTER:
3085 case INT32_STACK_SLOT:
3086 case UINT32_STACK_SLOT:
3087 case DOUBLE_STACK_SLOT:
3089 case COMPILED_STUB_FRAME:
3092 case ARGUMENTS_ADAPTOR_FRAME:
3093 case CONSTRUCT_STUB_FRAME:
3098 FATAL(
"Unexpected translation type");
3103 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
3105 const char* Translation::StringFor(
Opcode opcode) {
3106 #define TRANSLATION_OPCODE_CASE(item) case item: return #item;
3110 #undef TRANSLATION_OPCODE_CASE
3121 SlotRef SlotRefValueBuilder::ComputeSlotForNextArgument(
3123 TranslationIterator* iterator,
3124 DeoptimizationInputData* data,
3125 JavaScriptFrame* frame) {
3127 case Translation::BEGIN:
3129 case Translation::ARGUMENTS_ADAPTOR_FRAME:
3130 case Translation::CONSTRUCT_STUB_FRAME:
3131 case Translation::GETTER_STUB_FRAME:
3132 case Translation::SETTER_STUB_FRAME:
3136 case Translation::DUPLICATED_OBJECT: {
3137 return SlotRef::NewDuplicateObject(iterator->Next());
3140 case Translation::ARGUMENTS_OBJECT:
3141 return SlotRef::NewArgumentsObject(iterator->Next());
3143 case Translation::CAPTURED_OBJECT: {
3144 return SlotRef::NewDeferredObject(iterator->Next());
3148 case Translation::INT32_REGISTER:
3149 case Translation::UINT32_REGISTER:
3150 case Translation::DOUBLE_REGISTER:
3156 case Translation::STACK_SLOT: {
3157 int slot_index = iterator->Next();
3158 Address slot_addr = SlotAddress(frame, slot_index);
3159 return SlotRef(slot_addr, SlotRef::TAGGED);
3162 case Translation::INT32_STACK_SLOT: {
3163 int slot_index = iterator->Next();
3164 Address slot_addr = SlotAddress(frame, slot_index);
3165 return SlotRef(slot_addr, SlotRef::INT32);
3168 case Translation::UINT32_STACK_SLOT: {
3169 int slot_index = iterator->Next();
3170 Address slot_addr = SlotAddress(frame, slot_index);
3171 return SlotRef(slot_addr, SlotRef::UINT32);
3174 case Translation::DOUBLE_STACK_SLOT: {
3175 int slot_index = iterator->Next();
3176 Address slot_addr = SlotAddress(frame, slot_index);
3177 return SlotRef(slot_addr, SlotRef::DOUBLE);
3180 case Translation::LITERAL: {
3181 int literal_index = iterator->Next();
3182 return SlotRef(data->GetIsolate(),
3183 data->LiteralArray()->get(literal_index));
3186 case Translation::COMPILED_STUB_FRAME:
3191 FATAL(
"We should never get here - unexpected deopt info.");
3196 SlotRefValueBuilder::SlotRefValueBuilder(JavaScriptFrame* frame,
3197 int inlined_jsframe_index,
3198 int formal_parameter_count)
3199 : current_slot_(0), args_length_(-1), first_slot_index_(-1) {
3202 int deopt_index = Safepoint::kNoDeoptimizationIndex;
3203 DeoptimizationInputData* data =
3204 static_cast<OptimizedFrame*
>(frame)->GetDeoptimizationData(&deopt_index);
3205 TranslationIterator it(data->TranslationByteArray(),
3206 data->TranslationIndex(deopt_index)->value());
3208 CHECK_EQ(opcode, Translation::BEGIN);
3211 stack_frame_id_ = frame->fp();
3213 int jsframe_count = it.Next();
3214 CHECK_GT(jsframe_count, inlined_jsframe_index);
3215 int jsframes_to_skip = inlined_jsframe_index;
3216 int number_of_slots = -1;
3217 bool should_deopt =
false;
3218 while (number_of_slots != 0) {
3220 bool processed =
false;
3221 if (opcode == Translation::ARGUMENTS_ADAPTOR_FRAME) {
3222 if (jsframes_to_skip == 0) {
3223 CHECK_EQ(Translation::NumberOfOperandsFor(opcode), 2);
3226 int height = it.Next();
3229 it.Skip(Translation::NumberOfOperandsFor(
3234 first_slot_index_ = slot_refs_.length();
3235 args_length_ = height - 1;
3236 number_of_slots = height - 1;
3240 if (jsframes_to_skip == 0) {
3242 it.Skip(Translation::NumberOfOperandsFor(opcode));
3245 it.Skip(Translation::NumberOfOperandsFor(
3252 first_slot_index_ = slot_refs_.length();
3253 args_length_ = formal_parameter_count;
3254 number_of_slots = formal_parameter_count;
3258 }
else if (opcode != Translation::BEGIN &&
3259 opcode != Translation::CONSTRUCT_STUB_FRAME &&
3260 opcode != Translation::GETTER_STUB_FRAME &&
3261 opcode != Translation::SETTER_STUB_FRAME &&
3262 opcode != Translation::COMPILED_STUB_FRAME) {
3263 slot_refs_.Add(ComputeSlotForNextArgument(opcode, &it, data, frame));
3265 if (first_slot_index_ >= 0) {
3269 SlotRef& slot = slot_refs_.last();
3270 CHECK_NE(slot.Representation(), SlotRef::ARGUMENTS_OBJECT);
3271 number_of_slots += slot.GetChildrenCount();
3272 if (slot.Representation() == SlotRef::DEFERRED_OBJECT ||
3273 slot.Representation() == SlotRef::DUPLICATE_OBJECT) {
3274 should_deopt =
true;
3282 it.Skip(Translation::NumberOfOperandsFor(opcode));
3286 List<JSFunction*> functions(2);
3287 frame->GetFunctions(&functions);
3293 Handle<Object> SlotRef::GetValue(Isolate* isolate) {
3294 switch (representation_) {
3299 #if V8_TARGET_BIG_ENDIAN && V8_HOST_ARCH_64_BIT
3307 return isolate->factory()->NewNumberFromInt(value);
3312 #if V8_TARGET_BIG_ENDIAN && V8_HOST_ARCH_64_BIT
3318 return Handle<Object>(
Smi::FromInt(
static_cast<int>(value)), isolate);
3320 return isolate->factory()->NewNumber(
static_cast<double>(value));
3326 return isolate->factory()->NewNumber(value);
3333 FATAL(
"We should never get here - unexpected deopt info.");
3339 void SlotRefValueBuilder::Prepare(Isolate* isolate) {
3340 MaterializedObjectStore* materialized_store =
3341 isolate->materialized_object_store();
3342 previously_materialized_objects_ = materialized_store->Get(stack_frame_id_);
3343 prev_materialized_count_ = previously_materialized_objects_.is_null()
3344 ? 0 : previously_materialized_objects_->length();
3349 while (current_slot_ < first_slot_index_) {
3350 GetNext(isolate, 0);
3352 CHECK_EQ(current_slot_, first_slot_index_);
3356 Handle<Object> SlotRefValueBuilder::GetPreviouslyMaterialized(
3357 Isolate* isolate,
int length) {
3358 int object_index = materialized_objects_.length();
3359 Handle<Object> return_value = Handle<Object>(
3360 previously_materialized_objects_->get(object_index), isolate);
3361 materialized_objects_.Add(return_value);
3365 for (
int i = 0;
i < length;
i++) {
3366 SlotRef& slot = slot_refs_[current_slot_];
3371 length += slot.GetChildrenCount();
3375 if (slot.Representation() == SlotRef::DEFERRED_OBJECT ||
3376 slot.Representation() == SlotRef::DUPLICATE_OBJECT) {
3377 int nested_object_index = materialized_objects_.length();
3378 Handle<Object> nested_object = Handle<Object>(
3379 previously_materialized_objects_->get(nested_object_index),
3381 materialized_objects_.Add(nested_object);
3385 return return_value;
3389 Handle<Object> SlotRefValueBuilder::GetNext(Isolate* isolate,
int lvl) {
3390 SlotRef& slot = slot_refs_[current_slot_];
3392 switch (slot.Representation()) {
3393 case SlotRef::TAGGED:
3394 case SlotRef::INT32:
3395 case SlotRef::UINT32:
3396 case SlotRef::DOUBLE:
3397 case SlotRef::LITERAL: {
3398 return slot.GetValue(isolate);
3400 case SlotRef::ARGUMENTS_OBJECT: {
3404 materialized_objects_.Add(isolate->factory()->undefined_value());
3405 int length = slot.GetChildrenCount();
3406 for (
int i = 0;
i < length; ++
i) {
3408 GetNext(isolate, lvl + 1);
3410 return isolate->factory()->undefined_value();
3412 case SlotRef::DEFERRED_OBJECT: {
3413 int length = slot.GetChildrenCount();
3414 CHECK(slot_refs_[current_slot_].Representation() == SlotRef::LITERAL ||
3415 slot_refs_[current_slot_].Representation() == SlotRef::TAGGED);
3417 int object_index = materialized_objects_.length();
3418 if (object_index < prev_materialized_count_) {
3419 return GetPreviouslyMaterialized(isolate, length);
3422 Handle<Object> map_object = slot_refs_[current_slot_].GetValue(isolate);
3428 switch (
map->instance_type()) {
3433 Handle<Object>
object = GetNext(isolate, lvl + 1);
3434 materialized_objects_.Add(
object);
3439 for (
int i = 0;
i < length - 2;
i++) {
3440 GetNext(isolate, lvl + 1);
3445 Handle<JSObject>
object =
3447 materialized_objects_.Add(
object);
3448 Handle<Object> properties = GetNext(isolate, lvl + 1);
3449 Handle<Object> elements = GetNext(isolate, lvl + 1);
3450 object->set_properties(FixedArray::cast(*properties));
3451 object->set_elements(FixedArrayBase::cast(*elements));
3452 for (
int i = 0;
i < length - 3; ++
i) {
3453 Handle<Object> value = GetNext(isolate, lvl + 1);
3454 FieldIndex index = FieldIndex::ForPropertyIndex(object->map(),
i);
3455 object->FastPropertyAtPut(index, *value);
3460 Handle<JSArray>
object =
3461 isolate->factory()->NewJSArray(0,
map->elements_kind());
3462 materialized_objects_.Add(
object);
3463 Handle<Object> properties = GetNext(isolate, lvl + 1);
3464 Handle<Object> elements = GetNext(isolate, lvl + 1);
3465 Handle<Object> length = GetNext(isolate, lvl + 1);
3466 object->set_properties(FixedArray::cast(*properties));
3467 object->set_elements(FixedArrayBase::cast(*elements));
3468 object->set_length(*length);
3473 "[couldn't handle instance type %d]\n",
map->instance_type());
3481 case SlotRef::DUPLICATE_OBJECT: {
3482 int object_index = slot.DuplicateObjectId();
3483 Handle<Object>
object = materialized_objects_[object_index];
3484 materialized_objects_.Add(
object);
3492 FATAL(
"We should never get here - unexpected deopt slot kind.");
3497 void SlotRefValueBuilder::Finish(Isolate* isolate) {
3499 CHECK_EQ(slot_refs_.length(), current_slot_);
3501 if (materialized_objects_.length() > prev_materialized_count_) {
3504 Handle<FixedArray> array = isolate->factory()->NewFixedArray(
3505 materialized_objects_.length());
3506 for (
int i = 0;
i < materialized_objects_.length();
i++) {
3507 array->set(
i, *(materialized_objects_.at(
i)));
3509 isolate->materialized_object_store()->Set(stack_frame_id_, array);
3535 array->set(index, *materialized_objects);
3547 array->set(
i, array->get(
i + 1));
3570 if (array->length() >= length) {
3574 int new_length = length > 10 ? length : 10;
3575 if (new_length < 2 * array->length()) {
3576 new_length = 2 * array->length();
3581 for (
int i = 0;
i < array->length();
i++) {
3582 new_array->set(
i, array->get(
i));
3584 for (
int i = array->length();
i < length;
i++) {
3585 new_array->set(
i,
isolate()->heap()->undefined_value());
3594 bool has_arguments_adaptor,
3595 bool has_construct_stub) {
3611 if (has_arguments_adaptor) {
3612 output_frame = deoptimizer->
output_[frame_index - 1];
3631 v->VisitPointer(bit_cast<Object**>(&
function_));
virtual const char * NameOfCPURegister(int reg) const
static intptr_t CommitPageSize()
static Handle< Object > FunctionGetArguments(Handle< JSFunction > object)
static const int kFrameSize
void set_emit_debug_code(bool value)
void GetCode(CodeDesc *desc)
Code * builtin(Name name)
int GetEnvironmentParameterCount() const
StubFunctionMode function_mode() const
Register stack_parameter_count() const
bool IsEnvironmentParameterCountRegister(int index) const
ConstantPoolArray * constant_pool()
static const char * Kind2String(Kind kind)
bool marked_for_deoptimization()
void PrintDeoptLocation(FILE *out, int bailout_id)
SafepointEntry GetSafepointEntry(Address pc)
void set_marked_for_deoptimization(bool flag)
byte * instruction_start()
int SourcePosition(Address pc)
static const int kFrameSize
static const int kConstructorOffset
Object * OptimizedCodeListHead()
Object * OptimizedFunctionsListHead()
static Context * cast(Object *context)
void SetOptimizedCodeListHead(Object *head)
Context * native_context()
void SetOptimizedFunctionsListHead(Object *head)
Object * DeoptimizedCodeListHead()
void SetDeoptimizedCodeListHead(Object *head)
static void FlushICache(void *start, size_t size)
Smi * PcAndState(int index)
BailoutId AstId(int index)
virtual ~DeoptimizedFrameInfo()
void Iterate(ObjectVisitor *v)
Object ** expression_stack_
DeoptimizedFrameInfo(Deoptimizer *deoptimizer, int frame_index, bool has_arguments_adaptor, bool has_construct_stub)
void SetParameter(int index, Object *obj)
void SetExpression(int index, Object *obj)
MemoryChunk * deopt_entry_code_[Deoptimizer::kBailoutTypesWithCodeEntry]
int deopt_entry_code_entries_[Deoptimizer::kBailoutTypesWithCodeEntry]
DeoptimizerData(MemoryAllocator *allocator)
DeoptimizedFrameInfo * deoptimized_frame_info_
MemoryAllocator * allocator_
void Iterate(ObjectVisitor *v)
unsigned ComputeInputFrameSize() const
int has_alignment_padding_
BailoutType bailout_type_
void DoComputeAccessorStubFrame(TranslationIterator *iterator, int frame_index, bool is_setter_stub_frame)
List< Handle< Object > > * materialized_objects_
static Deoptimizer * Grab(Isolate *isolate)
Handle< Object > MaterializeNextHeapObject()
static void MarkAllCodeForContext(Context *native_context)
static const int kBailoutTypesWithCodeEntry
int ConvertJSFrameIndexToFrameIndex(int jsframe_index)
void AddObjectStart(intptr_t slot_address, int argc, bool is_arguments)
Code * FindOptimizedCode(JSFunction *function, Code *optimized_code)
void MaterializeHeapObjects(JavaScriptFrameIterator *it)
void AddDoubleValue(intptr_t slot_address, double value)
static int output_offset()
bool ArgumentsObjectIsAdapted(int object_index)
friend class FrameDescription
void MaterializeHeapNumbersForDebuggerInspectableFrame(Address parameters_top, uint32_t parameters_size, Address expressions_top, uint32_t expressions_size, DeoptimizedFrameInfo *info)
static void ComputeOutputFrames(Deoptimizer *deoptimizer)
static Deoptimizer * New(JSFunction *function, BailoutType type, unsigned bailout_id, Address from, int fp_to_sp_delta, Isolate *isolate)
List< Handle< Object > > * materialized_values_
static const int table_entry_size_
unsigned ComputeFixedSize(JSFunction *function) const
Object * ComputeLiteral(int index) const
static void DeoptimizeFunction(JSFunction *function)
void CopyDoubleRegisters(FrameDescription *output_frame)
int materialization_value_index_
void AddObjectDoubleValue(double value)
Deoptimizer(Isolate *isolate, JSFunction *function, BailoutType type, unsigned bailout_id, Address from, int fp_to_sp_delta, Code *optimized_code)
static void GenerateDeoptimizationEntries(MacroAssembler *masm, int count, BailoutType type)
Handle< JSFunction > function() const
void DoTranslateCommand(TranslationIterator *iterator, int frame_index, unsigned output_offset)
Code * FindDeoptimizingCode(Address addr)
List< ObjectMaterializationDescriptor > deferred_objects_
int prev_materialized_count_
unsigned ComputeOutgoingArgumentSize() const
List< Handle< JSFunction > > jsframe_functions_
static Address GetDeoptimizationEntry(Isolate *isolate, int id, BailoutType type, GetEntryMode mode=ENSURE_ENTRY_CODE)
static void DeoptimizeGlobalObject(JSObject *object)
Handle< FixedArray > previously_materialized_objects_
List< bool > jsframe_has_adapted_arguments_
static int input_offset()
static void EnsureCodeForDeoptimizationEntry(Isolate *isolate, BailoutType type, int max_entry_id)
static const char * MessageFor(BailoutType type)
static void PatchCodeForDeoptimization(Isolate *isolate, Code *code)
static DeoptimizedFrameInfo * DebuggerInspectableFrame(JavaScriptFrame *frame, int jsframe_index, Isolate *isolate)
@ CALCULATE_ENTRY_ADDRESS
static void VisitAllOptimizedFunctions(Isolate *isolate, OptimizedFunctionVisitor *visitor)
static bool TraceEnabledFor(BailoutType deopt_type, StackFrame::Type frame_type)
static const int kNotDeoptimizationEntry
void DoComputeOutputFrames()
static void DeoptimizeAll(Isolate *isolate)
static void VisitAllOptimizedFunctionsForContext(Context *context, OptimizedFunctionVisitor *visitor)
static const int kMaxNumberOfEntries
void DoComputeCompiledStubFrame(TranslationIterator *iterator, int frame_index)
static void DeoptimizeMarkedCode(Isolate *isolate)
void SetPlatformCompiledStubRegisters(FrameDescription *output_frame, CodeStubDescriptor *desc)
Handle< Code > compiled_code() const
static int GetDeoptimizedCodeCount(Isolate *isolate)
void DeleteFrameDescriptions()
Handle< JSFunction > ArgumentsObjectFunction(int object_index)
static int GetOutputInfo(DeoptimizationOutputData *data, BailoutId node_id, SharedFunctionInfo *shared)
void DoTranslateObject(TranslationIterator *iterator, int object_index, int field_index)
void DoComputeConstructStubFrame(TranslationIterator *iterator, int frame_index)
int materialization_object_index_
void AddObjectDuplication(intptr_t slot, int object_index)
List< HeapNumberMaterializationDescriptor< int > > deferred_objects_double_values_
void DoComputeJSFrame(TranslationIterator *iterator, int frame_index)
unsigned ComputeIncomingArgumentSize(JSFunction *function) const
FrameDescription ** output_
bool HasAlignmentPadding(JSFunction *function)
List< Object * > deferred_objects_tagged_values_
FrameDescription * input_
static void DeoptimizeMarkedCodeForContext(Context *native_context)
friend class DeoptimizedFrameInfo
static const int kMinNumberOfEntries
CodeTracer::Scope * trace_scope_
Handle< Object > MaterializeNextValue()
Isolate * isolate() const
void FillInputFrame(Address tos, JavaScriptFrame *frame)
void DoTranslateObjectAndSkip(TranslationIterator *iterator)
int jsframe_count() const
static size_t GetMaxDeoptTableSize()
static int GetDeoptimizationId(Isolate *isolate, Address addr, BailoutType type)
List< HeapNumberMaterializationDescriptor< Address > > deferred_heap_numbers_
void AddObjectTaggedValue(intptr_t value)
void DoComputeArgumentsAdaptorFrame(TranslationIterator *iterator, int frame_index)
static void DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo *info, Isolate *isolate)
unsigned GetOffsetFromSlotIndex(int slot_index)
int ComputeParametersCount()
void SetCallerFp(unsigned offset, intptr_t value)
uint32_t GetFrameSize() const
void SetTop(intptr_t top)
void SetContext(intptr_t context)
void SetCallerConstantPool(unsigned offset, intptr_t value)
intptr_t * GetFrameSlotPointer(unsigned offset)
static const uint32_t kZapUint32
JSFunction * GetFunction() const
intptr_t GetConstantPool() const
Object * GetExpression(int index)
double GetDoubleFrameSlot(unsigned offset)
Object * GetParameter(int index)
void SetFrameType(StackFrame::Type type)
FrameDescription(uint32_t frame_size, JSFunction *function)
intptr_t GetContext() const
void SetConstantPool(intptr_t constant_pool)
double GetDoubleRegister(unsigned n) const
void SetState(Smi *state)
StackFrame::Type GetFrameType() const
intptr_t GetFrameSlot(unsigned offset)
void SetRegister(unsigned n, intptr_t value)
intptr_t GetRegister(unsigned n) const
void SetCallerPc(unsigned offset, intptr_t value)
unsigned GetExpressionCount()
void SetFrameSlot(unsigned offset, intptr_t value)
void SetContinuation(intptr_t pc)
static const char * State2String(State state)
static Handle< T > cast(Handle< S > that)
static Handle< T > null()
Isolate * GetIsolate() const
Object * native_contexts_list() const
void public_set_materialized_objects(FixedArray *objects)
MarkCompactCollector * mark_compact_collector()
MaterializedObjectStore * materialized_object_store()
Object * FindCodeObject(Address a)
DeoptimizerData * deoptimizer_data()
ThreadLocalTop * thread_local_top()
CodeTracer * GetCodeTracer()
void PrintName(FILE *out=stdout)
bool has_adapted_arguments() const
static Register context_register()
JSFunction * function() const
static Register fp_register()
static Register constant_pool_pointer_register()
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
void Set(int index, const T &element)
static Handle< Map > GeneralizeAllFieldRepresentations(Handle< Map > map)
void InvalidateCode(Code *code)
void Set(Address fp, Handle< FixedArray > materialized_objects)
Handle< FixedArray > EnsureStackEntries(int size)
Handle< FixedArray > Get(Address fp)
Handle< FixedArray > GetStackEntries()
List< Address > frame_fps_
int StackIdToIndex(Address fp)
MemoryChunk * AllocateChunk(intptr_t reserve_area_size, intptr_t commit_area_size, Executability executable, Space *space)
void Free(MemoryChunk *chunk)
bool CommitArea(size_t requested)
static uint32_t & uint32_at(Address addr)
static Object *& Object_at(Address addr)
static int32_t & int32_at(Address addr)
void ShortPrint(FILE *out=stdout)
A class to uniformly access the prototype of any Object and walk its prototype chain.
Object * GetCurrent() const
void EvictFromOptimizedCodeMap(Code *optimized_code, const char *reason)
static const int kMaxValue
static Smi * FromInt(int value)
static bool IsValid(intptr_t value)
static const int kFixedFrameSizeFromFp
static const int kFixedFrameSize
static const int kCallerSPOffset
SmartArrayPointer< char > ToCString(AllowNullsFlag allow_nulls, RobustnessFlag robustness_flag, int offset, int length, int *length_output=0)
static Register constant_pool_pointer_register()
static Register context_register()
static Register fp_register()
#define TRANSLATION_OPCODE_LIST(V)
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf map
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS 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 enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric literals(0o77, 0b11)") DEFINE_BOOL(harmony_object_literals
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS 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_BOOL(enable_always_align_csp
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS 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 enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define LOG(isolate, Call)
#define CHECK_EQ(expected, value)
#define CHECK_NE(unexpected, value)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
static const char * TraceValueType(bool is_smi)
PerThreadAssertScopeDebugOnly< HEAP_ALLOCATION_ASSERT, false > DisallowHeapAllocation
TypeImpl< ZoneTypeConfig > Type
static MemoryChunk * AllocateCodeChunk(MemoryAllocator *allocator)
DwVfpRegister DoubleRegister
OStream & endl(OStream &os)
@ MUTABLE_HEAP_NUMBER_TYPE
Handle< T > handle(T *t, Isolate *isolate)
static LifetimePosition Max(LifetimePosition a, LifetimePosition b)
void PrintF(const char *format,...)
static const int kDeoptTableMaxEpilogueCodeSize
static double read_double_value(Address p)
void MemCopy(void *dest, const void *src, size_t size)
void CopyBytes(uint8_t *target, uint8_t *source)
Debugger support for the V8 JavaScript engine.
static const char * AllocationIndexToString(int index)
static int ToAllocationIndex(DwVfpRegister reg)
static const int kNumRegisters