43   eager_deoptimization_entry_code_ = 
NULL;
 
   44   lazy_deoptimization_entry_code_ = 
NULL;
 
   46   deoptimizing_code_list_ = 
NULL;
 
   47 #ifdef ENABLE_DEBUGGER_SUPPORT 
   48   deoptimized_frame_info_ = 
NULL;
 
   54   if (eager_deoptimization_entry_code_ != 
NULL) {
 
   55     Isolate::Current()->memory_allocator()->Free(
 
   56         eager_deoptimization_entry_code_);
 
   57     eager_deoptimization_entry_code_ = 
NULL;
 
   59   if (lazy_deoptimization_entry_code_ != 
NULL) {
 
   60     Isolate::Current()->memory_allocator()->Free(
 
   61         lazy_deoptimization_entry_code_);
 
   62     lazy_deoptimization_entry_code_ = 
NULL;
 
   67 #ifdef ENABLE_DEBUGGER_SUPPORT 
   68 void DeoptimizerData::Iterate(ObjectVisitor* v) {
 
   69   if (deoptimized_frame_info_ != 
NULL) {
 
   70     deoptimized_frame_info_->Iterate(v);
 
   84   ASSERT(isolate == Isolate::Current());
 
   99   ASSERT(isolate == Isolate::Current());
 
  102   result->DeleteFrameDescriptions();
 
  109   if (jsframe_index == 0) 
return 0;
 
  112   while (jsframe_index >= 0) {
 
  120   return frame_index - 1;
 
  124 #ifdef ENABLE_DEBUGGER_SUPPORT 
  125 DeoptimizedFrameInfo* Deoptimizer::DebuggerInspectableFrame(
 
  129   ASSERT(isolate == Isolate::Current());
 
  130   ASSERT(frame->is_optimized());
 
  135   Code* code = frame->LookupCode();
 
  139   SafepointEntry safepoint_entry = code->GetSafepointEntry(frame->pc());
 
  140   int deoptimization_index = safepoint_entry.deoptimization_index();
 
  141   ASSERT(deoptimization_index != Safepoint::kNoDeoptimizationIndex);
 
  145   unsigned stack_slots = code->stack_slots();
 
  146   unsigned fp_to_sp_delta = ((stack_slots + 2) * 
kPointerSize);
 
  151                                              deoptimization_index,
 
  155   Address tos = frame->fp() - fp_to_sp_delta;
 
  156   deoptimizer->FillInputFrame(tos, frame);
 
  168   bool has_arguments_adaptor =
 
  170       deoptimizer->output_[frame_index - 1]->
GetFrameType() ==
 
  173   int construct_offset = has_arguments_adaptor ? 2 : 1;
 
  174   bool has_construct_stub =
 
  175       frame_index >= construct_offset &&
 
  176       deoptimizer->output_[frame_index - construct_offset]->
GetFrameType() ==
 
  177       StackFrame::CONSTRUCT;
 
  181                                                         has_arguments_adaptor,
 
  187       deoptimizer->output_[
 
  188           has_arguments_adaptor ? (frame_index - 1) : frame_index];
 
  190   uint32_t parameters_size = (info->parameters_count() + 1) * 
kPointerSize;
 
  195   uint32_t expressions_size = info->expression_count() * 
kPointerSize;
 
  197       deoptimizer->output_[frame_index]->
GetTop());
 
  200   deoptimizer->DeleteFrameDescriptions();
 
  203   deoptimizer->MaterializeHeapNumbersForDebuggerInspectableFrame(
 
  204       parameters_top, parameters_size, expressions_top, expressions_size, info);
 
  213 void Deoptimizer::DeleteDebuggerInspectableFrame(DeoptimizedFrameInfo* info,
 
  215   ASSERT(isolate == Isolate::Current());
 
  216   ASSERT(isolate->deoptimizer_data()->deoptimized_frame_info_ == info);
 
  218   isolate->deoptimizer_data()->deoptimized_frame_info_ = 
NULL;
 
  222 void Deoptimizer::GenerateDeoptimizationEntries(MacroAssembler* masm,
 
  225   TableEntryGenerator generator(masm, type, count);
 
  226   generator.Generate();
 
  233     if (FLAG_trace_deopt) {
 
  235              reinterpret_cast<intptr_t>(context));
 
  252   if (FLAG_trace_deopt) {
 
  253     PrintF(
"[deoptimize all contexts]\n");
 
  270     Context* context, OptimizedFunctionVisitor* visitor) {
 
  273   ASSERT(context->IsGlobalContext());
 
  275   visitor->EnterContext(context);
 
  278   while (!element->IsUndefined()) {
 
  282     element = element_function->next_function_link();
 
  283     visitor->VisitFunction(element_function);
 
  285   visitor->LeaveContext(context);
 
  290     JSObject* 
object, OptimizedFunctionVisitor* visitor) {
 
  293   if (object->IsJSGlobalProxy()) {
 
  295     ASSERT(proto->IsJSGlobalObject());
 
  298   } 
else if (object->IsGlobalObject()) {
 
  306     OptimizedFunctionVisitor* visitor) {
 
  310   Object* context = Isolate::Current()->heap()->global_contexts_list();
 
  311   while (!context->IsUndefined()) {
 
  315     if (!global->IsUndefined()) {
 
  324 void Deoptimizer::HandleWeakDeoptimizedCode(
 
  328   RemoveDeoptimizingCode(*node->
code());
 
  330   node = Isolate::Current()->deoptimizer_data()->deoptimizing_code_list_;
 
  331   while (node != 
NULL) {
 
  332     ASSERT(node != reinterpret_cast<DeoptimizingCodeListNode*>(data));
 
  340   deoptimizer->DoComputeOutputFrames();
 
  344 Deoptimizer::Deoptimizer(
Isolate* isolate,
 
  345                          JSFunction* 
function,
 
  350                          Code* optimized_code)
 
  353       bailout_id_(bailout_id),
 
  356       fp_to_sp_delta_(fp_to_sp_delta),
 
  357       has_alignment_padding_(0),
 
  362       deferred_heap_numbers_(0) {
 
  363   if (FLAG_trace_deopt && type != 
OSR) {
 
  365       PrintF(
"**** DEOPT FOR DEBUGGER: ");
 
  369     function->PrintName();
 
  372            reinterpret_cast<intptr_t>(from),
 
  374   } 
else if (FLAG_trace_osr && type == 
OSR) {
 
  376     function->PrintName();
 
  379            reinterpret_cast<intptr_t>(from),
 
  382   function->shared()->increment_deopt_count();
 
  386     optimized_code_ = function_->
code();
 
  387     if (FLAG_trace_deopt && FLAG_code_comments) {
 
  389       const char* last_comment = 
NULL;
 
  390       int mask = RelocInfo::ModeMask(RelocInfo::COMMENT)
 
  392       for (RelocIterator it(optimized_code_, mask); !it.done(); it.next()) {
 
  393         RelocInfo* info = it.rinfo();
 
  394         if (info->rmode() == RelocInfo::COMMENT) {
 
  395           last_comment = 
reinterpret_cast<const char*
>(info->data());
 
  400           if (
id == bailout_id && last_comment != 
NULL) {
 
  401             PrintF(
"            %s\n", last_comment);
 
  407   } 
else if (type == 
LAZY) {
 
  408     optimized_code_ = FindDeoptimizingCodeFromAddress(from);
 
  410   } 
else if (type == 
OSR) {
 
  414     optimized_code_ = function_->
code();
 
  418     optimized_code_ = optimized_code;
 
  422   unsigned size = ComputeInputFrameSize();
 
  433 void Deoptimizer::DeleteFrameDescriptions() {
 
  435   for (
int i = 0; i < output_count_; ++i) {
 
  436     if (output_[i] != input_) 
delete output_[i];
 
  447   if (
id >= kNumberOfEntries) 
return NULL;
 
  451     if (data->eager_deoptimization_entry_code_ == 
NULL) {
 
  452       data->eager_deoptimization_entry_code_ = CreateCode(type);
 
  454     base = data->eager_deoptimization_entry_code_;
 
  456     if (data->lazy_deoptimization_entry_code_ == 
NULL) {
 
  457       data->lazy_deoptimization_entry_code_ = CreateCode(type);
 
  459     base = data->lazy_deoptimization_entry_code_;
 
  470     base = data->eager_deoptimization_entry_code_;
 
  472     base = data->lazy_deoptimization_entry_code_;
 
  475       addr < base->area_start() ||
 
  477           (kNumberOfEntries * table_entry_size_)) {
 
  481       static_cast<int>(addr - base->
area_start()) % table_entry_size_);
 
  482   return static_cast<int>(addr - base->
area_start()) / table_entry_size_;
 
  494   for (
int i = 0; i < length; i++) {
 
  495     if (data->
AstId(i) == smi_id) {
 
  499   PrintF(
"[couldn't find pc offset for node=%u]\n", 
id);
 
  516   while (node != 
NULL) {
 
  526 void Deoptimizer::DoComputeOutputFrames() {
 
  527   if (bailout_type_ == 
OSR) {
 
  528     DoComputeOsrOutputFrame();
 
  534   if (FLAG_trace_deopt) {
 
  536            (bailout_type_ == 
LAZY ? 
" (lazy)" : 
""),
 
  537            reinterpret_cast<intptr_t>(function_));
 
  539     PrintF(
" @%d]\n", bailout_id_);
 
  544   DeoptimizationInputData* input_data =
 
  546   unsigned node_id = input_data->AstId(bailout_id_)->value();
 
  547   ByteArray* translations = input_data->TranslationByteArray();
 
  548   unsigned translation_index =
 
  549       input_data->TranslationIndex(bailout_id_)->value();
 
  552   TranslationIterator iterator(translations, translation_index);
 
  555   ASSERT(Translation::BEGIN == opcode);
 
  559   int count = iterator.Next();
 
  563   for (
int i = 0; i < count; ++i) {
 
  566   output_count_ = count;
 
  569   for (
int i = 0; i < count; ++i) {
 
  574       case Translation::JS_FRAME:
 
  575         DoComputeJSFrame(&iterator, i);
 
  578       case Translation::ARGUMENTS_ADAPTOR_FRAME:
 
  579         DoComputeArgumentsAdaptorFrame(&iterator, i);
 
  581       case Translation::CONSTRUCT_STUB_FRAME:
 
  582         DoComputeConstructStubFrame(&iterator, i);
 
  591   if (FLAG_trace_deopt) {
 
  592     double ms = 
static_cast<double>(
OS::Ticks() - start) / 1000;
 
  593     int index = output_count_ - 1;  
 
  594     JSFunction* 
function = output_[index]->
GetFunction();
 
  596            reinterpret_cast<intptr_t>(
function));
 
  597     function->PrintName();
 
  601            output_[index]->GetPc(),
 
  603                static_cast<FullCodeGenerator::State>(
 
  604                    output_[index]->GetState()->value())),
 
  605            has_alignment_padding_ ? 
"with padding" : 
"no padding",
 
  613   for (
int i = 0; i < deferred_heap_numbers_.length(); i++) {
 
  614     HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i];
 
  616     if (FLAG_trace_deopt) {
 
  617       PrintF(
"Materializing a new heap number %p [%e] in slot %p\n",
 
  618              reinterpret_cast<void*>(*num),
 
  628 #ifdef ENABLE_DEBUGGER_SUPPORT 
  629 void Deoptimizer::MaterializeHeapNumbersForDebuggerInspectableFrame(
 
  631     uint32_t parameters_size,
 
  633     uint32_t expressions_size,
 
  634     DeoptimizedFrameInfo* info) {
 
  636   Address parameters_bottom = parameters_top + parameters_size;
 
  637   Address expressions_bottom = expressions_top + expressions_size;
 
  638   for (
int i = 0; i < deferred_heap_numbers_.length(); i++) {
 
  639     HeapNumberMaterializationDescriptor d = deferred_heap_numbers_[i];
 
  643     Address slot = d.slot_address();
 
  644     if (parameters_top <= slot && slot < parameters_bottom) {
 
  647       int index = (info->parameters_count() - 1) -
 
  650       if (FLAG_trace_deopt) {
 
  651         PrintF(
"Materializing a new heap number %p [%e] in slot %p" 
  652                "for parameter slot #%d\n",
 
  653                reinterpret_cast<void*>(*num),
 
  659       info->SetParameter(index, *num);
 
  660     } 
else if (expressions_top <= slot && slot < expressions_bottom) {
 
  663       int index = info->expression_count() - 1 -
 
  664           static_cast<int>(slot - expressions_top) / 
kPointerSize;
 
  666       if (FLAG_trace_deopt) {
 
  667         PrintF(
"Materializing a new heap number %p [%e] in slot %p" 
  668                "for expression slot #%d\n",
 
  669                reinterpret_cast<void*>(*num),
 
  675       info->SetExpression(index, *num);
 
  682 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator,
 
  684                                      unsigned output_offset) {
 
  687   const intptr_t kPlaceholder = 
reinterpret_cast<intptr_t
>(
Smi::FromInt(0));
 
  692   while (opcode == Translation::DUPLICATE) {
 
  694     iterator->Skip(Translation::NumberOfOperandsFor(opcode));
 
  699     case Translation::BEGIN:
 
  700     case Translation::JS_FRAME:
 
  701     case Translation::ARGUMENTS_ADAPTOR_FRAME:
 
  702     case Translation::CONSTRUCT_STUB_FRAME:
 
  703     case Translation::DUPLICATE:
 
  708       int input_reg = iterator->Next();
 
  709       intptr_t input_value = input_->
GetRegister(input_reg);
 
  710       if (FLAG_trace_deopt) {
 
  713             output_[frame_index]->GetTop() + output_offset,
 
  717         reinterpret_cast<Object*
>(input_value)->ShortPrint();
 
  720       output_[frame_index]->
SetFrameSlot(output_offset, input_value);
 
  724     case Translation::INT32_REGISTER: {
 
  725       int input_reg = iterator->Next();
 
  728       if (FLAG_trace_deopt) {
 
  730             "    0x%08" V8PRIxPTR 
": [top + %d] <- %" V8PRIdPTR " ; %s (%s)\n",
 
  731             output_[frame_index]->GetTop() + output_offset,
 
  735             is_smi ? 
"smi" : 
"heap number");
 
  738         intptr_t tagged_value =
 
  739             reinterpret_cast<intptr_t
>(
Smi::FromInt(static_cast<int>(value)));
 
  740         output_[frame_index]->
SetFrameSlot(output_offset, tagged_value);
 
  744         AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
 
  745                        static_cast<double>(static_cast<int32_t>(value)));
 
  746         output_[frame_index]->
SetFrameSlot(output_offset, kPlaceholder);
 
  751     case Translation::DOUBLE_REGISTER: {
 
  752       int input_reg = iterator->Next();
 
  754       if (FLAG_trace_deopt) {
 
  755         PrintF(
"    0x%08" V8PRIxPTR 
": [top + %d] <- %e ; %s\n",
 
  756                output_[frame_index]->GetTop() + output_offset,
 
  763       AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value);
 
  764       output_[frame_index]->
SetFrameSlot(output_offset, kPlaceholder);
 
  768     case Translation::STACK_SLOT: {
 
  769       int input_slot_index = iterator->Next();
 
  772       intptr_t input_value = input_->
GetFrameSlot(input_offset);
 
  773       if (FLAG_trace_deopt) {
 
  774         PrintF(
"    0x%08" V8PRIxPTR 
": ",
 
  775                output_[frame_index]->GetTop() + output_offset);
 
  776         PrintF(
"[top + %d] <- 0x%08" V8PRIxPTR 
" ; [sp + %d] ",
 
  780         reinterpret_cast<Object*
>(input_value)->ShortPrint();
 
  783       output_[frame_index]->
SetFrameSlot(output_offset, input_value);
 
  787     case Translation::INT32_STACK_SLOT: {
 
  788       int input_slot_index = iterator->Next();
 
  789       unsigned input_offset =
 
  793       if (FLAG_trace_deopt) {
 
  794         PrintF(
"    0x%08" V8PRIxPTR 
": ",
 
  795                output_[frame_index]->GetTop() + output_offset);
 
  796         PrintF(
"[top + %d] <- %" V8PRIdPTR 
" ; [sp + %d] (%s)\n",
 
  800                is_smi ? 
"smi" : 
"heap number");
 
  803         intptr_t tagged_value =
 
  804             reinterpret_cast<intptr_t
>(
Smi::FromInt(static_cast<int>(value)));
 
  805         output_[frame_index]->
SetFrameSlot(output_offset, tagged_value);
 
  809         AddDoubleValue(output_[frame_index]->GetTop() + output_offset,
 
  810                        static_cast<double>(static_cast<int32_t>(value)));
 
  811         output_[frame_index]->
SetFrameSlot(output_offset, kPlaceholder);
 
  816     case Translation::DOUBLE_STACK_SLOT: {
 
  817       int input_slot_index = iterator->Next();
 
  818       unsigned input_offset =
 
  821       if (FLAG_trace_deopt) {
 
  822         PrintF(
"    0x%08" V8PRIxPTR 
": [top + %d] <- %e ; [sp + %d]\n",
 
  823                output_[frame_index]->GetTop() + output_offset,
 
  830       AddDoubleValue(output_[frame_index]->GetTop() + output_offset, value);
 
  831       output_[frame_index]->
SetFrameSlot(output_offset, kPlaceholder);
 
  835     case Translation::LITERAL: {
 
  836       Object* literal = ComputeLiteral(iterator->Next());
 
  837       if (FLAG_trace_deopt) {
 
  838         PrintF(
"    0x%08" V8PRIxPTR 
": [top + %d] <- ",
 
  839                output_[frame_index]->GetTop() + output_offset,
 
  841         literal->ShortPrint();
 
  844       intptr_t value = 
reinterpret_cast<intptr_t
>(literal);
 
  845       output_[frame_index]->
SetFrameSlot(output_offset, value);
 
  849     case Translation::ARGUMENTS_OBJECT: {
 
  852       if (FLAG_trace_deopt) {
 
  853         PrintF(
"    0x%08" V8PRIxPTR 
": [top + %d] <- ",
 
  854                output_[frame_index]->GetTop() + output_offset,
 
  856         isolate_->
heap()->arguments_marker()->ShortPrint();
 
  857         PrintF(
" ; arguments object\n");
 
  859       intptr_t value = 
reinterpret_cast<intptr_t
>(
 
  860           isolate_->
heap()->arguments_marker());
 
  861       output_[frame_index]->
SetFrameSlot(output_offset, value);
 
  868 bool Deoptimizer::DoOsrTranslateCommand(TranslationIterator* iterator,
 
  875   uintptr_t input_value = input_->
GetFrameSlot(*input_offset);
 
  876   Object* input_object = 
reinterpret_cast<Object*
>(input_value);
 
  880   bool duplicate = (opcode == Translation::DUPLICATE);
 
  886     case Translation::BEGIN:
 
  887     case Translation::JS_FRAME:
 
  888     case Translation::ARGUMENTS_ADAPTOR_FRAME:
 
  889     case Translation::CONSTRUCT_STUB_FRAME:
 
  890     case Translation::DUPLICATE:
 
  895        int output_reg = iterator->Next();
 
  896        if (FLAG_trace_osr) {
 
  897          PrintF(
"    %s <- 0x%08" V8PRIxPTR 
" ; [sp + %d]\n",
 
  902        output->SetRegister(output_reg, input_value);
 
  906     case Translation::INT32_REGISTER: {
 
  908       if (!input_object->IsNumber()) 
return false;
 
  910       int output_reg = iterator->Next();
 
  911       int int32_value = input_object->IsSmi()
 
  913           : 
FastD2I(input_object->Number());
 
  915       if (!input_object->IsSmi() &&
 
  916           FastI2D(int32_value) != input_object->Number()) {
 
  917         if (FLAG_trace_osr) {
 
  918           PrintF(
"**** %g could not be converted to int32 ****\n",
 
  919                  input_object->Number());
 
  923       if (FLAG_trace_osr) {
 
  924         PrintF(
"    %s <- %d (int32) ; [sp + %d]\n",
 
  929       output->SetRegister(output_reg, int32_value);
 
  933     case Translation::DOUBLE_REGISTER: {
 
  935       if (!input_object->IsNumber()) 
return false;
 
  937       int output_reg = iterator->Next();
 
  938       double double_value = input_object->Number();
 
  939       if (FLAG_trace_osr) {
 
  940         PrintF(
"    %s <- %g (double) ; [sp + %d]\n",
 
  945       output->SetDoubleRegister(output_reg, double_value);
 
  949     case Translation::STACK_SLOT: {
 
  950       int output_index = iterator->Next();
 
  951       unsigned output_offset =
 
  952           output->GetOffsetFromSlotIndex(output_index);
 
  953       if (FLAG_trace_osr) {
 
  954         PrintF(
"    [sp + %d] <- 0x%08" V8PRIxPTR 
" ; [sp + %d] ",
 
  958         reinterpret_cast<Object*
>(input_value)->ShortPrint();
 
  961       output->SetFrameSlot(output_offset, input_value);
 
  965     case Translation::INT32_STACK_SLOT: {
 
  967       if (!input_object->IsNumber()) 
return false;
 
  969       int output_index = iterator->Next();
 
  970       unsigned output_offset =
 
  971           output->GetOffsetFromSlotIndex(output_index);
 
  972       int int32_value = input_object->IsSmi()
 
  976       if (!input_object->IsSmi() &&
 
  977           FastI2D(int32_value) != input_object->Number()) {
 
  978         if (FLAG_trace_osr) {
 
  979           PrintF(
"**** %g could not be converted to int32 ****\n",
 
  980                  input_object->Number());
 
  984       if (FLAG_trace_osr) {
 
  985         PrintF(
"    [sp + %d] <- %d (int32) ; [sp + %d]\n",
 
  990       output->SetFrameSlot(output_offset, int32_value);
 
  994     case Translation::DOUBLE_STACK_SLOT: {
 
  999       if (!input_object->IsNumber()) 
return false;
 
 1001       int output_index = iterator->Next();
 
 1002       unsigned output_offset =
 
 1003           output->GetOffsetFromSlotIndex(output_index);
 
 1004       double double_value = input_object->Number();
 
 1005       uint64_t int_value = BitCast<uint64_t, double>(double_value);
 
 1008       if (FLAG_trace_osr) {
 
 1009         PrintF(
"    [sp + %d] <- 0x%08x (upper bits of %g) ; [sp + %d]\n",
 
 1010                output_offset + kUpperOffset,
 
 1014         PrintF(
"    [sp + %d] <- 0x%08x (lower bits of %g) ; [sp + %d]\n",
 
 1015                output_offset + kLowerOffset,
 
 1020       output->SetFrameSlot(output_offset + kLowerOffset, lower);
 
 1021       output->SetFrameSlot(output_offset + kUpperOffset, upper);
 
 1025     case Translation::LITERAL: {
 
 1031     case Translation::ARGUMENTS_OBJECT: {
 
 1048                                       Code* replacement_code) {
 
 1056   for (uint32_t i = 0; i < table_length; ++i) {
 
 1063     stack_check_cursor += 2 * 
kIntSize;
 
 1070                                        Code* replacement_code) {
 
 1078   for (uint32_t i = 0; i < table_length; ++i) {
 
 1085     stack_check_cursor += 2 * 
kIntSize;
 
 1090 unsigned Deoptimizer::ComputeInputFrameSize()
 const {
 
 1091   unsigned fixed_size = ComputeFixedSize(function_);
 
 1094   unsigned result = fixed_size + fp_to_sp_delta_ - (2 * 
kPointerSize);
 
 1096   if (bailout_type_ == 
OSR) {
 
 1102     unsigned stack_slots = optimized_code_->
stack_slots();
 
 1103     unsigned outgoing_size = ComputeOutgoingArgumentSize();
 
 1111 unsigned Deoptimizer::ComputeFixedSize(JSFunction* 
function)
 const {
 
 1114   return ComputeIncomingArgumentSize(
function) +
 
 1119 unsigned Deoptimizer::ComputeIncomingArgumentSize(JSFunction* 
function)
 const {
 
 1122   unsigned arguments = 
function->shared()->formal_parameter_count() + 1;
 
 1127 unsigned Deoptimizer::ComputeOutgoingArgumentSize()
 const {
 
 1129       optimized_code_->deoptimization_data());
 
 1130   unsigned height = data->ArgumentsStackHeight(bailout_id_)->value();
 
 1135 Object* Deoptimizer::ComputeLiteral(
int index)
 const {
 
 1137       optimized_code_->deoptimization_data());
 
 1138   FixedArray* literals = data->LiteralArray();
 
 1139   return literals->
get(index);
 
 1143 void Deoptimizer::AddDoubleValue(intptr_t slot_address,
 
 1145   HeapNumberMaterializationDescriptor value_desc(
 
 1146       reinterpret_cast<Address>(slot_address), value);
 
 1147   deferred_heap_numbers_.
Add(value_desc);
 
 1151 MemoryChunk* Deoptimizer::CreateCode(BailoutType type) {
 
 1158   MacroAssembler masm(Isolate::Current(), 
NULL, 16 * 
KB);
 
 1159   masm.set_emit_debug_code(
false);
 
 1160   GenerateDeoptimizationEntries(&masm, kNumberOfEntries, type);
 
 1162   masm.GetCode(&desc);
 
 1163   ASSERT(desc.reloc_size == 0);
 
 1165   MemoryChunk* chunk =
 
 1166       Isolate::Current()->memory_allocator()->AllocateChunk(desc.instr_size,
 
 1169   ASSERT(chunk->area_size() >= desc.instr_size);
 
 1170   if (chunk == 
NULL) {
 
 1173   memcpy(chunk->area_start(), desc.buffer, desc.instr_size);
 
 1179 Code* Deoptimizer::FindDeoptimizingCodeFromAddress(
Address addr) {
 
 1181       Isolate::Current()->deoptimizer_data()->deoptimizing_code_list_;
 
 1182   while (node != 
NULL) {
 
 1183     if (node->code()->contains(addr)) 
return *node->code();
 
 1184     node = node->next();
 
 1190 void Deoptimizer::RemoveDeoptimizingCode(Code* code) {
 
 1191   DeoptimizerData* data = Isolate::Current()->deoptimizer_data();
 
 1192   ASSERT(data->deoptimizing_code_list_ != 
NULL);
 
 1196   while (current != 
NULL) {
 
 1197     if (*current->code() == code) {
 
 1200         data->deoptimizing_code_list_ = current->next();
 
 1202         prev->set_next(current->next());
 
 1209     current = current->next();
 
 1218                                    JSFunction* 
function)
 
 1219     : frame_size_(frame_size),
 
 1220       function_(function),
 
 1224       context_(kZapUint32) {
 
 1231   for (
unsigned o = 0; o < frame_size; o += 
kPointerSize) {
 
 1237 int FrameDescription::ComputeFixedSize() {
 
 1244   if (slot_index >= 0) {
 
 1260     case StackFrame::JAVA_SCRIPT:
 
 1261       return function_->shared()->formal_parameter_count();
 
 1265       return reinterpret_cast<Smi*
>(*GetFrameSlotPointer(0))->value();
 
 1279   return reinterpret_cast<Object*
>(*GetFrameSlotPointer(offset));
 
 1284   ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_);
 
 1291   ASSERT_EQ(StackFrame::JAVA_SCRIPT, type_);
 
 1293   return reinterpret_cast<Object*
>(*GetFrameSlotPointer(offset));
 
 1297 void TranslationBuffer::Add(
int32_t value, 
Zone* zone) {
 
 1299   bool is_negative = (value < 0);
 
 1300   uint32_t bits = ((is_negative ? -value : value) << 1) |
 
 1301       static_cast<int32_t>(is_negative);
 
 1305     uint32_t next = bits >> 7;
 
 1306     contents_.Add(((bits << 1) & 0xFF) | (next != 0), zone);
 
 1308   } 
while (bits != 0);
 
 1312 int32_t TranslationIterator::Next() {
 
 1316   for (
int i = 0; 
true; i += 7) {
 
 1318     uint8_t next = 
buffer_->get(index_++);
 
 1319     bits |= (next >> 1) << i;
 
 1320     if ((next & 1) == 0) 
break;
 
 1323   bool is_negative = (bits & 1) == 1;
 
 1325   return is_negative ? -result : result;
 
 1329 Handle<ByteArray> TranslationBuffer::CreateByteArray() {
 
 1330   int length = contents_.length();
 
 1331   Handle<ByteArray> result =
 
 1332       Isolate::Current()->factory()->NewByteArray(length, 
TENURED);
 
 1333   memcpy(result->GetDataStartAddress(), contents_.ToVector().start(), length);
 
 1338 void Translation::BeginConstructStubFrame(
int literal_id, 
unsigned height) {
 
 1339   buffer_->Add(CONSTRUCT_STUB_FRAME, zone());
 
 1340   buffer_->Add(literal_id, zone());
 
 1345 void Translation::BeginArgumentsAdaptorFrame(
int literal_id, 
unsigned height) {
 
 1346   buffer_->Add(ARGUMENTS_ADAPTOR_FRAME, zone());
 
 1347   buffer_->Add(literal_id, zone());
 
 1352 void Translation::BeginJSFrame(
int node_id, 
int literal_id, 
unsigned height) {
 
 1353   buffer_->Add(JS_FRAME, zone());
 
 1354   buffer_->Add(node_id, zone());
 
 1355   buffer_->Add(literal_id, zone());
 
 1360 void Translation::StoreRegister(Register reg) {
 
 1362   buffer_->Add(reg.code(), zone());
 
 1366 void Translation::StoreInt32Register(Register reg) {
 
 1367   buffer_->Add(INT32_REGISTER, zone());
 
 1368   buffer_->Add(reg.code(), zone());
 
 1373   buffer_->Add(DOUBLE_REGISTER, zone());
 
 1378 void Translation::StoreStackSlot(
int index) {
 
 1379   buffer_->Add(STACK_SLOT, zone());
 
 1384 void Translation::StoreInt32StackSlot(
int index) {
 
 1385   buffer_->Add(INT32_STACK_SLOT, zone());
 
 1390 void Translation::StoreDoubleStackSlot(
int index) {
 
 1391   buffer_->Add(DOUBLE_STACK_SLOT, zone());
 
 1396 void Translation::StoreLiteral(
int literal_id) {
 
 1397   buffer_->Add(LITERAL, zone());
 
 1398   buffer_->Add(literal_id, zone());
 
 1402 void Translation::StoreArgumentsObject() {
 
 1403   buffer_->Add(ARGUMENTS_OBJECT, zone());
 
 1407 void Translation::MarkDuplicate() {
 
 1408   buffer_->Add(DUPLICATE, zone());
 
 1412 int Translation::NumberOfOperandsFor(
Opcode opcode) {
 
 1414     case ARGUMENTS_OBJECT:
 
 1418     case INT32_REGISTER:
 
 1419     case DOUBLE_REGISTER:
 
 1421     case INT32_STACK_SLOT:
 
 1422     case DOUBLE_STACK_SLOT:
 
 1426     case ARGUMENTS_ADAPTOR_FRAME:
 
 1427     case CONSTRUCT_STUB_FRAME:
 
 1437 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER) 
 1439 const char* Translation::StringFor(
Opcode opcode) {
 
 1445     case ARGUMENTS_ADAPTOR_FRAME:
 
 1446       return "ARGUMENTS_ADAPTOR_FRAME";
 
 1447     case CONSTRUCT_STUB_FRAME:
 
 1448       return "CONSTRUCT_STUB_FRAME";
 
 1451     case INT32_REGISTER:
 
 1452       return "INT32_REGISTER";
 
 1453     case DOUBLE_REGISTER:
 
 1454       return "DOUBLE_REGISTER";
 
 1456       return "STACK_SLOT";
 
 1457     case INT32_STACK_SLOT:
 
 1458       return "INT32_STACK_SLOT";
 
 1459     case DOUBLE_STACK_SLOT:
 
 1460       return "DOUBLE_STACK_SLOT";
 
 1463     case ARGUMENTS_OBJECT:
 
 1464       return "ARGUMENTS_OBJECT";
 
 1476   GlobalHandles* global_handles = Isolate::Current()->global_handles();
 
 1479   global_handles->
MakeWeak(reinterpret_cast<Object**>(code_.location()),
 
 1481                            Deoptimizer::HandleWeakDeoptimizedCode);
 
 1486   GlobalHandles* global_handles = Isolate::Current()->global_handles();
 
 1487   global_handles->
Destroy(reinterpret_cast<Object**>(code_.location()));
 
 1494 SlotRef SlotRef::ComputeSlotForNextArgument(TranslationIterator* iterator,
 
 1501     case Translation::BEGIN:
 
 1502     case Translation::JS_FRAME:
 
 1503     case Translation::ARGUMENTS_ADAPTOR_FRAME:
 
 1504     case Translation::CONSTRUCT_STUB_FRAME:
 
 1508     case Translation::ARGUMENTS_OBJECT:
 
 1513     case Translation::INT32_REGISTER:
 
 1514     case Translation::DOUBLE_REGISTER:
 
 1515     case Translation::DUPLICATE:
 
 1521     case Translation::STACK_SLOT: {
 
 1522       int slot_index = iterator->Next();
 
 1523       Address slot_addr = SlotAddress(frame, slot_index);
 
 1524       return SlotRef(slot_addr, SlotRef::TAGGED);
 
 1527     case Translation::INT32_STACK_SLOT: {
 
 1528       int slot_index = iterator->Next();
 
 1529       Address slot_addr = SlotAddress(frame, slot_index);
 
 1530       return SlotRef(slot_addr, SlotRef::INT32);
 
 1533     case Translation::DOUBLE_STACK_SLOT: {
 
 1534       int slot_index = iterator->Next();
 
 1535       Address slot_addr = SlotAddress(frame, slot_index);
 
 1536       return SlotRef(slot_addr, SlotRef::DOUBLE);
 
 1539     case Translation::LITERAL: {
 
 1540       int literal_index = iterator->Next();
 
 1541       return SlotRef(data->LiteralArray()->
get(literal_index));
 
 1550 void SlotRef::ComputeSlotsForArguments(Vector<SlotRef>* args_slots,
 
 1551                                        TranslationIterator* it,
 
 1552                                        DeoptimizationInputData* data,
 
 1553                                        JavaScriptFrame* frame) {
 
 1557   it->Skip(Translation::NumberOfOperandsFor(
 
 1558       static_cast<Translation::Opcode>(it->Next())));
 
 1561   for (
int i = 0; i < args_slots->length(); ++i) {
 
 1562     (*args_slots)[i] = ComputeSlotForNextArgument(it, data, frame);
 
 1567 Vector<SlotRef> SlotRef::ComputeSlotMappingForArguments(
 
 1568     JavaScriptFrame* frame,
 
 1569     int inlined_jsframe_index,
 
 1571   AssertNoAllocation no_gc;
 
 1573   DeoptimizationInputData* data =
 
 1574       static_cast<OptimizedFrame*
>(frame)->GetDeoptimizationData(&deopt_index);
 
 1575   TranslationIterator it(data->TranslationByteArray(),
 
 1576                          data->TranslationIndex(deopt_index)->value());
 
 1578   ASSERT(opcode == Translation::BEGIN);
 
 1580   int jsframe_count = it.Next();
 
 1582   ASSERT(jsframe_count > inlined_jsframe_index);
 
 1583   int jsframes_to_skip = inlined_jsframe_index;
 
 1586     if (opcode == Translation::ARGUMENTS_ADAPTOR_FRAME) {
 
 1587       if (jsframes_to_skip == 0) {
 
 1588         ASSERT(Translation::NumberOfOperandsFor(opcode) == 2);
 
 1591         int height = it.Next();
 
 1595         Vector<SlotRef> args_slots =
 
 1597         ComputeSlotsForArguments(&args_slots, &it, data, frame);
 
 1600     } 
else if (opcode == Translation::JS_FRAME) {
 
 1601       if (jsframes_to_skip == 0) {
 
 1603         it.Skip(Translation::NumberOfOperandsFor(opcode));
 
 1609         Vector<SlotRef> args_slots =
 
 1611         ComputeSlotsForArguments(&args_slots, &it, data, frame);
 
 1618     it.Skip(Translation::NumberOfOperandsFor(opcode));
 
 1622   return Vector<SlotRef>();
 
 1625 #ifdef ENABLE_DEBUGGER_SUPPORT 
 1627 DeoptimizedFrameInfo::DeoptimizedFrameInfo(Deoptimizer* deoptimizer,
 
 1629                                            bool has_arguments_adaptor,
 
 1630                                            bool has_construct_stub) {
 
 1631   FrameDescription* output_frame = deoptimizer->output_[frame_index];
 
 1632   function_ = output_frame->GetFunction();
 
 1633   has_construct_stub_ = has_construct_stub;
 
 1634   expression_count_ = output_frame->GetExpressionCount();
 
 1635   expression_stack_ = 
new Object*[expression_count_];
 
 1638   Code* code = 
Code::cast(Isolate::Current()->heap()->FindCodeObject(pc));
 
 1639   source_position_ = code->SourcePosition(pc);
 
 1641   for (
int i = 0; i < expression_count_; i++) {
 
 1642     SetExpression(i, output_frame->GetExpression(i));
 
 1645   if (has_arguments_adaptor) {
 
 1646     output_frame = deoptimizer->output_[frame_index - 1];
 
 1650   parameters_count_ = output_frame->ComputeParametersCount();
 
 1651   parameters_ = 
new Object*[parameters_count_];
 
 1652   for (
int i = 0; i < parameters_count_; i++) {
 
 1653     SetParameter(i, output_frame->GetParameter(i));
 
 1658 DeoptimizedFrameInfo::~DeoptimizedFrameInfo() {
 
 1659   delete[] expression_stack_;
 
 1660   delete[] parameters_;
 
 1664 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) {
 
 1665   v->VisitPointer(BitCast<Object**>(&function_));
 
 1666   v->VisitPointers(parameters_, parameters_ + parameters_count_);
 
 1667   v->VisitPointers(expression_stack_, expression_stack_ + expression_count_);
 
 1670 #endif  // ENABLE_DEBUGGER_SUPPORT 
DeoptimizingCodeListNode * next() const 
 
void Destroy(Object **location)
 
Object * function() const 
 
static Object *& Object_at(Address addr)
 
void PrintF(const char *format,...)
 
Handle< Code > code() const 
 
void SourceCodePrint(StringStream *accumulator, int max_length)
 
static Smi * FromInt(int value)
 
unsigned stack_check_table_offset()
 
unsigned GetOffsetFromSlotIndex(int slot_index)
 
static void RevertStackCheckCode(Code *unoptimized_code, Code *check_code, Code *replacement_code)
 
void SetFrameSlot(unsigned offset, intptr_t value)
 
kPropertyAccessorsOffset kNamedPropertyHandlerOffset kInstanceTemplateOffset kAccessCheckInfoOffset kEvalFrominstructionsOffsetOffset kThisPropertyAssignmentsOffset kNeedsAccessCheckBit kIsExpressionBit kHasOnlySimpleThisPropertyAssignments kUsesArguments formal_parameter_count
 
static void ComputeOutputFrames(Deoptimizer *deoptimizer)
 
static Handle< T > cast(Handle< S > that)
 
static const int kNoNumber
 
virtual void EnterContext(Context *context)
 
#define ASSERT(condition)
 
static void DeoptimizeFunction(JSFunction *function)
 
static Context * cast(Object *context)
 
static void DeoptimizeAll()
 
double GetDoubleRegister(unsigned n) const 
 
Handle< Object > NewNumber(double value, PretenureFlag pretenure=NOT_TENURED)
 
void SetFrameType(StackFrame::Type type)
 
StringInputBuffer *const buffer_
 
DeoptimizingCodeListNode(Code *code)
 
virtual void VisitFunction(JSFunction *function)
 
static Code * cast(Object *obj)
 
static Smi * cast(Object *object)
 
static const char * AllocationIndexToString(int index)
 
static const int kNumRegisters
 
virtual void LeaveContext(Context *context)
 
void ClearOptimizedFunctions()
 
SmartArrayPointer< char > ToCString(AllowNullsFlag allow_nulls, RobustnessFlag robustness_flag, int offset, int length, int *length_output=0)
 
int ComputeParametersCount()
 
JSFunction * GetFunction() const 
 
static void DeoptimizeGlobalObject(JSObject *object)
 
DwVfpRegister DoubleRegister
 
virtual const char * NameOfCPURegister(int reg) const 
 
Handle< Object > Create(Object *value)
 
static bool IsValid(intptr_t value)
 
Smi * PcAndState(int index)
 
byte * instruction_start()
 
Object * OptimizedFunctionsListHead()
 
void SetRegister(unsigned n, intptr_t value)
 
friend class DeoptimizingCodeListNode
 
static int GetDeoptimizedCodeCount(Isolate *isolate)
 
unsigned GetExpressionCount()
 
static const char * State2String(State state)
 
static int GetOutputInfo(DeoptimizationOutputData *data, unsigned node_id, SharedFunctionInfo *shared)
 
static const int kFixedFrameSize
 
static void PatchStackCheckCode(Code *unoptimized_code, Code *check_code, Code *replacement_code)
 
~DeoptimizingCodeListNode()
 
static Vector< T > New(int length)
 
DeoptimizerData * deoptimizer_data()
 
uint32_t GetFrameSize() const 
 
static void VisitAllOptimizedFunctionsForContext(Context *context, OptimizedFunctionVisitor *visitor)
 
#define ASSERT_LT(v1, v2)
 
static void RevertStackCheckCodeAt(Code *unoptimized_code, Address pc_after, Code *check_code, Code *replacement_code)
 
int32_t DoubleToInt32(double x)
 
intptr_t GetFrameSlot(unsigned offset)
 
friend class DeoptimizedFrameInfo
 
void MaterializeHeapNumbers()
 
static Address GetDeoptimizationEntry(int id, BailoutType type)
 
static int ToAllocationIndex(DwVfpRegister reg)
 
static Deoptimizer * Grab(Isolate *isolate)
 
static const int kNotDeoptimizationEntry
 
#define ASSERT_EQ(v1, v2)
 
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
 
friend class FrameDescription
 
StackFrame::Type GetFrameType() const 
 
#define ASSERT_NE(v1, v2)
 
double GetDoubleFrameSlot(unsigned offset)
 
FrameDescription(uint32_t frame_size, JSFunction *function)
 
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
 
static void VisitAllOptimizedFunctions(OptimizedFunctionVisitor *visitor)
 
static uint32_t & uint32_at(Address addr)
 
#define RUNTIME_ENTRY(name, nargs, ressize)
 
static void VisitAllOptimizedFunctionsForGlobalObject(JSObject *object, OptimizedFunctionVisitor *visitor)
 
int ConvertJSFrameIndexToFrameIndex(int jsframe_index)
 
static void FlushICache(void *start, size_t size)
 
void MakeWeak(Object **location, void *parameter, WeakReferenceCallback callback)
 
intptr_t GetRegister(unsigned n) const 
 
static GlobalObject * cast(Object *obj)
 
SmartArrayPointer< const char > ToCString() const 
 
int jsframe_count() const 
 
static void FatalProcessOutOfMemory(const char *location, bool take_snapshot=false)
 
static int GetDeoptimizationId(Address addr, BailoutType type)
 
static JSObject * cast(Object *obj)
 
static void PatchStackCheckCodeAt(Code *unoptimized_code, Address pc_after, Code *check_code, Code *replacement_code)
 
static Deoptimizer * New(JSFunction *function, BailoutType type, unsigned bailout_id, Address from, int fp_to_sp_delta, Isolate *isolate)
 
static int input_offset()
 
Object * GetExpression(int index)
 
Object * GetParameter(int index)
 
static JSFunction * cast(Object *obj)