~yolanda.robla/ubuntu/trusty/nodejs/add_distribution

« back to all changes in this revision

Viewing changes to deps/v8/src/frames.cc

  • Committer: Package Import Robot
  • Author(s): Jérémy Lal
  • Date: 2013-08-14 00:16:46 UTC
  • mfrom: (7.1.40 sid)
  • Revision ID: package-import@ubuntu.com-20130814001646-bzlysfh8sd6mukbo
Tags: 0.10.15~dfsg1-4
* Update 2005 patch, adding a handful of tests that can fail on
  slow platforms.
* Add 1004 patch to fix test failures when writing NaN to buffer
  on mipsel.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2011 the V8 project authors. All rights reserved.
 
1
// Copyright 2012 the V8 project authors. All rights reserved.
2
2
// Redistribution and use in source and binary forms, with or without
3
3
// modification, are permitted provided that the following conditions are
4
4
// met:
31
31
#include "deoptimizer.h"
32
32
#include "frames-inl.h"
33
33
#include "full-codegen.h"
 
34
#include "lazy-instance.h"
34
35
#include "mark-compact.h"
35
36
#include "safepoint-table.h"
36
37
#include "scopeinfo.h"
41
42
namespace v8 {
42
43
namespace internal {
43
44
 
 
45
 
 
46
static ReturnAddressLocationResolver return_address_location_resolver = NULL;
 
47
 
 
48
 
 
49
// Resolves pc_address through the resolution address function if one is set.
 
50
static inline Address* ResolveReturnAddressLocation(Address* pc_address) {
 
51
  if (return_address_location_resolver == NULL) {
 
52
    return pc_address;
 
53
  } else {
 
54
    return reinterpret_cast<Address*>(
 
55
        return_address_location_resolver(
 
56
            reinterpret_cast<uintptr_t>(pc_address)));
 
57
  }
 
58
}
 
59
 
 
60
 
44
61
// Iterator that supports traversing the stack handlers of a
45
62
// particular frame. Needs to know the top of the handler chain.
46
63
class StackHandlerIterator BASE_EMBEDDED {
155
172
    ASSERT(fp_ != NULL);
156
173
    state.fp = fp_;
157
174
    state.sp = sp_;
158
 
    state.pc_address =
159
 
        reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_));
 
175
    state.pc_address = ResolveReturnAddressLocation(
 
176
        reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp_)));
160
177
    type = StackFrame::ComputeType(isolate(), &state);
161
178
  }
162
179
  if (SingletonFor(type) == NULL) return;
366
383
 
367
384
 
368
385
Code* StackFrame::GetSafepointData(Isolate* isolate,
369
 
                                   Address pc,
 
386
                                   Address inner_pointer,
370
387
                                   SafepointEntry* safepoint_entry,
371
388
                                   unsigned* stack_slots) {
372
 
  PcToCodeCache::PcToCodeCacheEntry* entry =
373
 
      isolate->pc_to_code_cache()->GetCacheEntry(pc);
 
389
  InnerPointerToCodeCache::InnerPointerToCodeCacheEntry* entry =
 
390
      isolate->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer);
374
391
  if (!entry->safepoint_entry.is_valid()) {
375
 
    entry->safepoint_entry = entry->code->GetSafepointEntry(pc);
 
392
    entry->safepoint_entry = entry->code->GetSafepointEntry(inner_pointer);
376
393
    ASSERT(entry->safepoint_entry.is_valid());
377
394
  } else {
378
 
    ASSERT(entry->safepoint_entry.Equals(entry->code->GetSafepointEntry(pc)));
 
395
    ASSERT(entry->safepoint_entry.Equals(
 
396
        entry->code->GetSafepointEntry(inner_pointer)));
379
397
  }
380
398
 
381
399
  // Fill in the results and return the code.
392
410
}
393
411
 
394
412
 
 
413
#ifdef DEBUG
 
414
static bool GcSafeCodeContains(HeapObject* object, Address addr);
 
415
#endif
 
416
 
 
417
 
395
418
void StackFrame::IteratePc(ObjectVisitor* v,
396
419
                           Address* pc_address,
397
420
                           Code* holder) {
398
421
  Address pc = *pc_address;
399
 
  ASSERT(holder->contains(pc));
 
422
  ASSERT(GcSafeCodeContains(holder, pc));
400
423
  unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start());
401
424
  Object* code = holder;
402
425
  v->VisitPointer(&code);
408
431
}
409
432
 
410
433
 
 
434
void StackFrame::SetReturnAddressLocationResolver(
 
435
    ReturnAddressLocationResolver resolver) {
 
436
  ASSERT(return_address_location_resolver == NULL);
 
437
  return_address_location_resolver = resolver;
 
438
}
 
439
 
 
440
 
411
441
StackFrame::Type StackFrame::ComputeType(Isolate* isolate, State* state) {
412
442
  ASSERT(state->fp != NULL);
413
443
  if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
439
469
}
440
470
 
441
471
 
 
472
Address StackFrame::UnpaddedFP() const {
 
473
#if defined(V8_TARGET_ARCH_IA32)
 
474
  if (!is_optimized()) return fp();
 
475
  int32_t alignment_state = Memory::int32_at(
 
476
    fp() + JavaScriptFrameConstants::kDynamicAlignmentStateOffset);
 
477
 
 
478
  return (alignment_state == kAlignmentPaddingPushed) ?
 
479
    (fp() + kPointerSize) : fp();
 
480
#else
 
481
  return fp();
 
482
#endif
 
483
}
 
484
 
 
485
 
442
486
Code* EntryFrame::unchecked_code() const {
443
487
  return HEAP->raw_unchecked_js_entry_code();
444
488
}
479
523
 
480
524
 
481
525
void ExitFrame::ComputeCallerState(State* state) const {
482
 
  // Setup the caller state.
 
526
  // Set up the caller state.
483
527
  state->sp = caller_sp();
484
528
  state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset);
485
 
  state->pc_address
486
 
      = reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset);
 
529
  state->pc_address = ResolveReturnAddressLocation(
 
530
      reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset));
487
531
}
488
532
 
489
533
 
517
561
void ExitFrame::FillState(Address fp, Address sp, State* state) {
518
562
  state->sp = sp;
519
563
  state->fp = fp;
520
 
  state->pc_address = reinterpret_cast<Address*>(sp - 1 * kPointerSize);
 
564
  state->pc_address = ResolveReturnAddressLocation(
 
565
      reinterpret_cast<Address*>(sp - 1 * kPointerSize));
521
566
}
522
567
 
523
568
 
552
597
void StandardFrame::ComputeCallerState(State* state) const {
553
598
  state->sp = caller_sp();
554
599
  state->fp = caller_fp();
555
 
  state->pc_address = reinterpret_cast<Address*>(ComputePCAddress(fp()));
 
600
  state->pc_address = ResolveReturnAddressLocation(
 
601
      reinterpret_cast<Address*>(ComputePCAddress(fp())));
556
602
}
557
603
 
558
604
 
646
692
}
647
693
 
648
694
 
 
695
void JavaScriptFrame::SetParameterValue(int index, Object* value) const {
 
696
  Memory::Object_at(GetParameterSlot(index)) = value;
 
697
}
 
698
 
 
699
 
649
700
bool JavaScriptFrame::IsConstructor() const {
650
701
  Address fp = caller_fp();
651
702
  if (has_adapted_arguments()) {
705
756
}
706
757
 
707
758
 
 
759
void JavaScriptFrame::PrintTop(FILE* file,
 
760
                               bool print_args,
 
761
                               bool print_line_number) {
 
762
  // constructor calls
 
763
  HandleScope scope;
 
764
  AssertNoAllocation no_allocation;
 
765
  JavaScriptFrameIterator it;
 
766
  while (!it.done()) {
 
767
    if (it.frame()->is_java_script()) {
 
768
      JavaScriptFrame* frame = it.frame();
 
769
      if (frame->IsConstructor()) PrintF(file, "new ");
 
770
      // function name
 
771
      Object* maybe_fun = frame->function();
 
772
      if (maybe_fun->IsJSFunction()) {
 
773
        JSFunction* fun = JSFunction::cast(maybe_fun);
 
774
        fun->PrintName();
 
775
        Code* js_code = frame->unchecked_code();
 
776
        Address pc = frame->pc();
 
777
        int code_offset =
 
778
            static_cast<int>(pc - js_code->instruction_start());
 
779
        PrintF("+%d", code_offset);
 
780
        SharedFunctionInfo* shared = fun->shared();
 
781
        if (print_line_number) {
 
782
          Code* code = Code::cast(
 
783
              v8::internal::Isolate::Current()->heap()->FindCodeObject(pc));
 
784
          int source_pos = code->SourcePosition(pc);
 
785
          Object* maybe_script = shared->script();
 
786
          if (maybe_script->IsScript()) {
 
787
            Handle<Script> script(Script::cast(maybe_script));
 
788
            int line = GetScriptLineNumberSafe(script, source_pos) + 1;
 
789
            Object* script_name_raw = script->name();
 
790
            if (script_name_raw->IsString()) {
 
791
              String* script_name = String::cast(script->name());
 
792
              SmartArrayPointer<char> c_script_name =
 
793
                  script_name->ToCString(DISALLOW_NULLS,
 
794
                                         ROBUST_STRING_TRAVERSAL);
 
795
              PrintF(file, " at %s:%d", *c_script_name, line);
 
796
            } else {
 
797
              PrintF(file, " at <unknown>:%d", line);
 
798
            }
 
799
          } else {
 
800
            PrintF(file, " at <unknown>:<unknown>");
 
801
          }
 
802
        }
 
803
      } else {
 
804
        PrintF("<unknown>");
 
805
      }
 
806
 
 
807
      if (print_args) {
 
808
        // function arguments
 
809
        // (we are intentionally only printing the actually
 
810
        // supplied parameters, not all parameters required)
 
811
        PrintF(file, "(this=");
 
812
        frame->receiver()->ShortPrint(file);
 
813
        const int length = frame->ComputeParametersCount();
 
814
        for (int i = 0; i < length; i++) {
 
815
          PrintF(file, ", ");
 
816
          frame->GetParameter(i)->ShortPrint(file);
 
817
        }
 
818
        PrintF(file, ")");
 
819
      }
 
820
      break;
 
821
    }
 
822
    it.Advance();
 
823
  }
 
824
}
 
825
 
 
826
 
708
827
void FrameSummary::Print() {
709
828
  PrintF("receiver: ");
710
829
  receiver_->ShortPrint();
718
837
}
719
838
 
720
839
 
 
840
JSFunction* OptimizedFrame::LiteralAt(FixedArray* literal_array,
 
841
                                      int literal_id) {
 
842
  if (literal_id == Translation::kSelfLiteralId) {
 
843
    return JSFunction::cast(function());
 
844
  }
 
845
 
 
846
  return JSFunction::cast(literal_array->get(literal_id));
 
847
}
 
848
 
 
849
 
721
850
void OptimizedFrame::Summarize(List<FrameSummary>* frames) {
722
851
  ASSERT(frames->length() == 0);
723
852
  ASSERT(is_optimized());
724
853
 
725
854
  int deopt_index = Safepoint::kNoDeoptimizationIndex;
726
855
  DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
 
856
  FixedArray* literal_array = data->LiteralArray();
727
857
 
728
858
  // BUG(3243555): Since we don't have a lazy-deopt registered at
729
859
  // throw-statements, we can't use the translation at the call-site of
739
869
                         data->TranslationIndex(deopt_index)->value());
740
870
  Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
741
871
  ASSERT(opcode == Translation::BEGIN);
742
 
  int frame_count = it.Next();
 
872
  it.Next();  // Drop frame count.
 
873
  int jsframe_count = it.Next();
743
874
 
744
875
  // We create the summary in reverse order because the frames
745
876
  // in the deoptimization translation are ordered bottom-to-top.
746
 
  int i = frame_count;
 
877
  bool is_constructor = IsConstructor();
 
878
  int i = jsframe_count;
747
879
  while (i > 0) {
748
880
    opcode = static_cast<Translation::Opcode>(it.Next());
749
 
    if (opcode == Translation::FRAME) {
750
 
      // We don't inline constructor calls, so only the first, outermost
751
 
      // frame can be a constructor frame in case of inlining.
752
 
      bool is_constructor = (i == frame_count) && IsConstructor();
753
 
 
 
881
    if (opcode == Translation::JS_FRAME) {
754
882
      i--;
755
 
      int ast_id = it.Next();
756
 
      int function_id = it.Next();
 
883
      BailoutId ast_id = BailoutId(it.Next());
 
884
      JSFunction* function = LiteralAt(literal_array, it.Next());
757
885
      it.Next();  // Skip height.
758
 
      JSFunction* function =
759
 
          JSFunction::cast(data->LiteralArray()->get(function_id));
760
886
 
761
887
      // The translation commands are ordered and the receiver is always
762
888
      // at the first position. Since we are always at a call when we need
800
926
 
801
927
      FrameSummary summary(receiver, function, code, pc_offset, is_constructor);
802
928
      frames->Add(summary);
 
929
      is_constructor = false;
 
930
    } else if (opcode == Translation::CONSTRUCT_STUB_FRAME) {
 
931
      // The next encountered JS_FRAME will be marked as a constructor call.
 
932
      it.Skip(Translation::NumberOfOperandsFor(opcode));
 
933
      ASSERT(!is_constructor);
 
934
      is_constructor = true;
803
935
    } else {
804
936
      // Skip over operands to advance to the next opcode.
805
937
      it.Skip(Translation::NumberOfOperandsFor(opcode));
806
938
    }
807
939
  }
 
940
  ASSERT(!is_constructor);
808
941
}
809
942
 
810
943
 
819
952
  // back to a slow search in this case to find the original optimized
820
953
  // code object.
821
954
  if (!code->contains(pc())) {
822
 
    code = isolate()->pc_to_code_cache()->GcSafeFindCodeForPc(pc());
 
955
    code = isolate()->inner_pointer_to_code_cache()->
 
956
        GcSafeFindCodeForInnerPointer(pc());
823
957
  }
824
958
  ASSERT(code != NULL);
825
959
  ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION);
843
977
  Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
844
978
  ASSERT(opcode == Translation::BEGIN);
845
979
  USE(opcode);
846
 
  int frame_count = it.Next();
847
 
  return frame_count;
 
980
  it.Next();  // Drop frame count.
 
981
  int jsframe_count = it.Next();
 
982
  return jsframe_count;
848
983
}
849
984
 
850
985
 
854
989
 
855
990
  int deopt_index = Safepoint::kNoDeoptimizationIndex;
856
991
  DeoptimizationInputData* data = GetDeoptimizationData(&deopt_index);
 
992
  FixedArray* literal_array = data->LiteralArray();
857
993
 
858
994
  TranslationIterator it(data->TranslationByteArray(),
859
995
                         data->TranslationIndex(deopt_index)->value());
860
996
  Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
861
997
  ASSERT(opcode == Translation::BEGIN);
862
 
  int frame_count = it.Next();
 
998
  it.Next();  // Drop frame count.
 
999
  int jsframe_count = it.Next();
863
1000
 
864
1001
  // We insert the frames in reverse order because the frames
865
1002
  // in the deoptimization translation are ordered bottom-to-top.
866
 
  while (frame_count > 0) {
 
1003
  while (jsframe_count > 0) {
867
1004
    opcode = static_cast<Translation::Opcode>(it.Next());
868
 
    if (opcode == Translation::FRAME) {
869
 
      frame_count--;
 
1005
    if (opcode == Translation::JS_FRAME) {
 
1006
      jsframe_count--;
870
1007
      it.Next();  // Skip ast id.
871
 
      int function_id = it.Next();
 
1008
      JSFunction* function = LiteralAt(literal_array, it.Next());
872
1009
      it.Next();  // Skip height.
873
 
      JSFunction* function =
874
 
          JSFunction::cast(data->LiteralArray()->get(function_id));
875
1010
      functions->Add(function);
876
1011
    } else {
877
1012
      // Skip over operands to advance to the next opcode.
881
1016
}
882
1017
 
883
1018
 
 
1019
int ArgumentsAdaptorFrame::GetNumberOfIncomingArguments() const {
 
1020
  return Smi::cast(GetExpression(0))->value();
 
1021
}
 
1022
 
 
1023
 
884
1024
Address ArgumentsAdaptorFrame::GetCallerStackPointer() const {
885
1025
  return fp() + StandardFrameConstants::kCallerSPOffset;
886
1026
}
927
1067
  if (IsConstructor()) accumulator->Add("new ");
928
1068
  accumulator->PrintFunction(function, receiver, &code);
929
1069
 
930
 
  Handle<SerializedScopeInfo> scope_info(SerializedScopeInfo::Empty());
 
1070
  // Get scope information for nicer output, if possible. If code is NULL, or
 
1071
  // doesn't contain scope info, scope_info will return 0 for the number of
 
1072
  // parameters, stack local variables, context local variables, stack slots,
 
1073
  // or context slots.
 
1074
  Handle<ScopeInfo> scope_info(ScopeInfo::Empty());
931
1075
 
932
1076
  if (function->IsJSFunction()) {
933
1077
    Handle<SharedFunctionInfo> shared(JSFunction::cast(function)->shared());
934
 
    scope_info = Handle<SerializedScopeInfo>(shared->scope_info());
 
1078
    scope_info = Handle<ScopeInfo>(shared->scope_info());
935
1079
    Object* script_obj = shared->script();
936
1080
    if (script_obj->IsScript()) {
937
1081
      Handle<Script> script(Script::cast(script_obj));
956
1100
 
957
1101
  accumulator->Add("(this=%o", receiver);
958
1102
 
959
 
  // Get scope information for nicer output, if possible. If code is
960
 
  // NULL, or doesn't contain scope info, info will return 0 for the
961
 
  // number of parameters, stack slots, or context slots.
962
 
  ScopeInfo<PreallocatedStorage> info(*scope_info);
963
 
 
964
1103
  // Print the parameters.
965
1104
  int parameters_count = ComputeParametersCount();
966
1105
  for (int i = 0; i < parameters_count; i++) {
968
1107
    // If we have a name for the parameter we print it. Nameless
969
1108
    // parameters are either because we have more actual parameters
970
1109
    // than formal parameters or because we have no scope information.
971
 
    if (i < info.number_of_parameters()) {
972
 
      accumulator->PrintName(*info.parameter_name(i));
 
1110
    if (i < scope_info->ParameterCount()) {
 
1111
      accumulator->PrintName(scope_info->ParameterName(i));
973
1112
      accumulator->Add("=");
974
1113
    }
975
1114
    accumulator->Add("%o", GetParameter(i));
987
1126
  accumulator->Add(" {\n");
988
1127
 
989
1128
  // Compute the number of locals and expression stack elements.
990
 
  int stack_locals_count = info.number_of_stack_slots();
991
 
  int heap_locals_count = info.number_of_context_slots();
 
1129
  int stack_locals_count = scope_info->StackLocalCount();
 
1130
  int heap_locals_count = scope_info->ContextLocalCount();
992
1131
  int expressions_count = ComputeExpressionsCount();
993
1132
 
994
1133
  // Print stack-allocated local variables.
997
1136
  }
998
1137
  for (int i = 0; i < stack_locals_count; i++) {
999
1138
    accumulator->Add("  var ");
1000
 
    accumulator->PrintName(*info.stack_slot_name(i));
 
1139
    accumulator->PrintName(scope_info->StackLocalName(i));
1001
1140
    accumulator->Add(" = ");
1002
1141
    if (i < expressions_count) {
1003
1142
      accumulator->Add("%o", GetExpression(i));
1014
1153
  }
1015
1154
 
1016
1155
  // Print heap-allocated local variables.
1017
 
  if (heap_locals_count > Context::MIN_CONTEXT_SLOTS) {
 
1156
  if (heap_locals_count > 0) {
1018
1157
    accumulator->Add("  // heap-allocated locals\n");
1019
1158
  }
1020
 
  for (int i = Context::MIN_CONTEXT_SLOTS; i < heap_locals_count; i++) {
 
1159
  for (int i = 0; i < heap_locals_count; i++) {
1021
1160
    accumulator->Add("  var ");
1022
 
    accumulator->PrintName(*info.context_slot_name(i));
 
1161
    accumulator->PrintName(scope_info->ContextLocalName(i));
1023
1162
    accumulator->Add(" = ");
1024
1163
    if (context != NULL) {
1025
1164
      if (i < context->length()) {
1026
 
        accumulator->Add("%o", context->get(i));
 
1165
        accumulator->Add("%o", context->get(Context::MIN_CONTEXT_SLOTS + i));
1027
1166
      } else {
1028
1167
        accumulator->Add(
1029
1168
            "// warning: missing context slot - inconsistent frame?");
1092
1231
  StackHandlerIterator it(this, top_handler());
1093
1232
  ASSERT(!it.done());
1094
1233
  StackHandler* handler = it.handler();
1095
 
  ASSERT(handler->is_entry());
 
1234
  ASSERT(handler->is_js_entry());
1096
1235
  handler->Iterate(v, LookupCode());
1097
1236
#ifdef DEBUG
1098
1237
  // Make sure that the entry frame does not contain more than one
1155
1294
// -------------------------------------------------------------------------
1156
1295
 
1157
1296
 
1158
 
Code* PcToCodeCache::GcSafeCastToCode(HeapObject* object, Address pc) {
 
1297
static Map* GcSafeMapOfCodeSpaceObject(HeapObject* object) {
 
1298
  MapWord map_word = object->map_word();
 
1299
  return map_word.IsForwardingAddress() ?
 
1300
      map_word.ToForwardingAddress()->map() : map_word.ToMap();
 
1301
}
 
1302
 
 
1303
 
 
1304
static int GcSafeSizeOfCodeSpaceObject(HeapObject* object) {
 
1305
  return object->SizeFromMap(GcSafeMapOfCodeSpaceObject(object));
 
1306
}
 
1307
 
 
1308
 
 
1309
#ifdef DEBUG
 
1310
static bool GcSafeCodeContains(HeapObject* code, Address addr) {
 
1311
  Map* map = GcSafeMapOfCodeSpaceObject(code);
 
1312
  ASSERT(map == code->GetHeap()->code_map());
 
1313
  Address start = code->address();
 
1314
  Address end = code->address() + code->SizeFromMap(map);
 
1315
  return start <= addr && addr < end;
 
1316
}
 
1317
#endif
 
1318
 
 
1319
 
 
1320
Code* InnerPointerToCodeCache::GcSafeCastToCode(HeapObject* object,
 
1321
                                                Address inner_pointer) {
1159
1322
  Code* code = reinterpret_cast<Code*>(object);
1160
 
  ASSERT(code != NULL && code->contains(pc));
 
1323
  ASSERT(code != NULL && GcSafeCodeContains(code, inner_pointer));
1161
1324
  return code;
1162
1325
}
1163
1326
 
1164
1327
 
1165
 
Code* PcToCodeCache::GcSafeFindCodeForPc(Address pc) {
 
1328
Code* InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer(
 
1329
    Address inner_pointer) {
1166
1330
  Heap* heap = isolate_->heap();
1167
 
  // Check if the pc points into a large object chunk.
1168
 
  LargeObjectChunk* chunk = heap->lo_space()->FindChunkContainingPc(pc);
1169
 
  if (chunk != NULL) return GcSafeCastToCode(chunk->GetObject(), pc);
1170
 
 
1171
 
  // Iterate through the 8K page until we reach the end or find an
1172
 
  // object starting after the pc.
1173
 
  Page* page = Page::FromAddress(pc);
1174
 
  HeapObjectIterator iterator(page, heap->GcSafeSizeOfOldObjectFunction());
1175
 
  HeapObject* previous = NULL;
 
1331
  // Check if the inner pointer points into a large object chunk.
 
1332
  LargePage* large_page = heap->lo_space()->FindPage(inner_pointer);
 
1333
  if (large_page != NULL) {
 
1334
    return GcSafeCastToCode(large_page->GetObject(), inner_pointer);
 
1335
  }
 
1336
 
 
1337
  // Iterate through the page until we reach the end or find an object starting
 
1338
  // after the inner pointer.
 
1339
  Page* page = Page::FromAddress(inner_pointer);
 
1340
 
 
1341
  Address addr = page->skip_list()->StartFor(inner_pointer);
 
1342
 
 
1343
  Address top = heap->code_space()->top();
 
1344
  Address limit = heap->code_space()->limit();
 
1345
 
1176
1346
  while (true) {
1177
 
    HeapObject* next = iterator.next();
1178
 
    if (next == NULL || next->address() >= pc) {
1179
 
      return GcSafeCastToCode(previous, pc);
 
1347
    if (addr == top && addr != limit) {
 
1348
      addr = limit;
 
1349
      continue;
1180
1350
    }
1181
 
    previous = next;
 
1351
 
 
1352
    HeapObject* obj = HeapObject::FromAddress(addr);
 
1353
    int obj_size = GcSafeSizeOfCodeSpaceObject(obj);
 
1354
    Address next_addr = addr + obj_size;
 
1355
    if (next_addr > inner_pointer) return GcSafeCastToCode(obj, inner_pointer);
 
1356
    addr = next_addr;
1182
1357
  }
1183
1358
}
1184
1359
 
1185
1360
 
1186
 
PcToCodeCache::PcToCodeCacheEntry* PcToCodeCache::GetCacheEntry(Address pc) {
 
1361
InnerPointerToCodeCache::InnerPointerToCodeCacheEntry*
 
1362
    InnerPointerToCodeCache::GetCacheEntry(Address inner_pointer) {
1187
1363
  isolate_->counters()->pc_to_code()->Increment();
1188
 
  ASSERT(IsPowerOf2(kPcToCodeCacheSize));
 
1364
  ASSERT(IsPowerOf2(kInnerPointerToCodeCacheSize));
1189
1365
  uint32_t hash = ComputeIntegerHash(
1190
 
      static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pc)),
 
1366
      static_cast<uint32_t>(reinterpret_cast<uintptr_t>(inner_pointer)),
1191
1367
      v8::internal::kZeroHashSeed);
1192
 
  uint32_t index = hash & (kPcToCodeCacheSize - 1);
1193
 
  PcToCodeCacheEntry* entry = cache(index);
1194
 
  if (entry->pc == pc) {
 
1368
  uint32_t index = hash & (kInnerPointerToCodeCacheSize - 1);
 
1369
  InnerPointerToCodeCacheEntry* entry = cache(index);
 
1370
  if (entry->inner_pointer == inner_pointer) {
1195
1371
    isolate_->counters()->pc_to_code_cached()->Increment();
1196
 
    ASSERT(entry->code == GcSafeFindCodeForPc(pc));
 
1372
    ASSERT(entry->code == GcSafeFindCodeForInnerPointer(inner_pointer));
1197
1373
  } else {
1198
1374
    // Because this code may be interrupted by a profiling signal that
1199
 
    // also queries the cache, we cannot update pc before the code has
1200
 
    // been set. Otherwise, we risk trying to use a cache entry before
 
1375
    // also queries the cache, we cannot update inner_pointer before the code
 
1376
    // has been set. Otherwise, we risk trying to use a cache entry before
1201
1377
    // the code has been computed.
1202
 
    entry->code = GcSafeFindCodeForPc(pc);
 
1378
    entry->code = GcSafeFindCodeForInnerPointer(inner_pointer);
1203
1379
    entry->safepoint_entry.Reset();
1204
 
    entry->pc = pc;
 
1380
    entry->inner_pointer = inner_pointer;
1205
1381
  }
1206
1382
  return entry;
1207
1383
}
1210
1386
// -------------------------------------------------------------------------
1211
1387
 
1212
1388
int NumRegs(RegList reglist) {
1213
 
  int n = 0;
1214
 
  while (reglist != 0) {
1215
 
    n++;
1216
 
    reglist &= reglist - 1;  // clear one bit
1217
 
  }
1218
 
  return n;
 
1389
  return CompilerIntrinsics::CountSetBits(reglist);
1219
1390
}
1220
1391
 
1221
1392
 
1222
1393
struct JSCallerSavedCodeData {
1223
 
  JSCallerSavedCodeData() {
1224
 
    int i = 0;
1225
 
    for (int r = 0; r < kNumRegs; r++)
1226
 
      if ((kJSCallerSaved & (1 << r)) != 0)
1227
 
        reg_code[i++] = r;
1228
 
 
1229
 
    ASSERT(i == kNumJSCallerSaved);
1230
 
  }
1231
1394
  int reg_code[kNumJSCallerSaved];
1232
1395
};
1233
1396
 
1234
 
 
1235
 
static const JSCallerSavedCodeData kCallerSavedCodeData;
1236
 
 
 
1397
JSCallerSavedCodeData caller_saved_code_data;
 
1398
 
 
1399
void SetUpJSCallerSavedCodeData() {
 
1400
  int i = 0;
 
1401
  for (int r = 0; r < kNumRegs; r++)
 
1402
    if ((kJSCallerSaved & (1 << r)) != 0)
 
1403
      caller_saved_code_data.reg_code[i++] = r;
 
1404
 
 
1405
  ASSERT(i == kNumJSCallerSaved);
 
1406
}
1237
1407
 
1238
1408
int JSCallerSavedCode(int n) {
1239
1409
  ASSERT(0 <= n && n < kNumJSCallerSaved);
1240
 
  return kCallerSavedCodeData.reg_code[n];
 
1410
  return caller_saved_code_data.reg_code[n];
1241
1411
}
1242
1412
 
1243
1413
 
1251
1421
STACK_FRAME_TYPE_LIST(DEFINE_WRAPPER)
1252
1422
#undef DEFINE_WRAPPER
1253
1423
 
1254
 
static StackFrame* AllocateFrameCopy(StackFrame* frame) {
 
1424
static StackFrame* AllocateFrameCopy(StackFrame* frame, Zone* zone) {
1255
1425
#define FRAME_TYPE_CASE(type, field) \
1256
1426
  case StackFrame::type: { \
1257
1427
    field##_Wrapper* wrapper = \
1258
 
        new field##_Wrapper(*(reinterpret_cast<field*>(frame))); \
 
1428
        new(zone) field##_Wrapper(*(reinterpret_cast<field*>(frame))); \
1259
1429
    return &wrapper->frame_; \
1260
1430
  }
1261
1431
 
1267
1437
  return NULL;
1268
1438
}
1269
1439
 
1270
 
Vector<StackFrame*> CreateStackMap() {
1271
 
  ZoneList<StackFrame*> list(10);
 
1440
Vector<StackFrame*> CreateStackMap(Zone* zone) {
 
1441
  ZoneList<StackFrame*> list(10, zone);
1272
1442
  for (StackFrameIterator it; !it.done(); it.Advance()) {
1273
 
    StackFrame* frame = AllocateFrameCopy(it.frame());
1274
 
    list.Add(frame);
 
1443
    StackFrame* frame = AllocateFrameCopy(it.frame(), zone);
 
1444
    list.Add(frame, zone);
1275
1445
  }
1276
1446
  return list.ToVector();
1277
1447
}