当前位置: 首页>>代码示例>>C++>>正文


C++ PseudoStack类代码示例

本文整理汇总了C++中PseudoStack的典型用法代码示例。如果您正苦于以下问题:C++ PseudoStack类的具体用法?C++ PseudoStack怎么用?C++ PseudoStack使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了PseudoStack类的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: mozilla_sampler_shutdown

void mozilla_sampler_shutdown()
{
  sInitCount--;

  if (sInitCount > 0)
    return;

  // Save the profile on shutdown if requested.
  GeckoSampler *t = tlsTicker.get();
  if (t) {
    const char *val = getenv("MOZ_PROFILER_SHUTDOWN");
    if (val) {
      std::ofstream stream;
      stream.open(val);
      if (stream.is_open()) {
        t->ToStreamAsJSON(stream);
        stream.close();
      }
    }
  }

  profiler_stop();

#ifndef SPS_STANDALONE
  set_stderr_callback(nullptr);
#endif

  Sampler::Shutdown();

#ifdef SPS_STANDALONE
  mozilla::TimeStamp::Shutdown();
#endif

  PseudoStack *stack = tlsPseudoStack.get();
  stack->deref();
  tlsPseudoStack.set(nullptr);

#ifdef MOZ_TASK_TRACER
  mozilla::tasktracer::ShutdownTaskTracer();
#endif
}
开发者ID:cliqz-oss,项目名称:browser-f,代码行数:41,代码来源:platform.cpp

示例2: mergeNativeBacktrace

static void mergeNativeBacktrace(ThreadProfile &aProfile, const PCArray &array) {
  aProfile.addTag(ProfileEntry('s', "(root)"));

  PseudoStack* stack = aProfile.GetPseudoStack();
  uint32_t pseudoStackPos = 0;

  /* We have two stacks, the native C stack we extracted from unwinding,
   * and the pseudostack we managed during execution. We want to consolidate
   * the two in order. We do so by merging using the approximate stack address
   * when each entry was push. When pushing JS entry we may not now the stack
   * address in which case we have a NULL stack address in which case we assume
   * that it follows immediatly the previous element.
   *
   *  C Stack | Address    --  Pseudo Stack | Address
   *  main()  | 0x100          run_js()     | 0x40
   *  start() | 0x80           jsCanvas()   | NULL
   *  timer() | 0x50           drawLine()   | NULL
   *  azure() | 0x10
   *
   * Merged: main(), start(), timer(), run_js(), jsCanvas(), drawLine(), azure()
   */
  // i is the index in C stack starting at main and decreasing
  // pseudoStackPos is the position in the Pseudo stack starting
  // at the first frame (run_js in the example) and increasing.
  for (size_t i = array.count; i > 0; --i) {
    while (pseudoStackPos < stack->stackSize()) {
      volatile StackEntry& entry = stack->mStack[pseudoStackPos];

      if (entry.stackAddress() < array.sp_array[i-1] && entry.stackAddress())
        break;

      addProfileEntry(entry, aProfile, stack, array.array[0]);
      pseudoStackPos++;
    }

    aProfile.addTag(ProfileEntry('l', (void*)array.array[i-1]));
  }
}
开发者ID:,项目名称:,代码行数:38,代码来源:

示例3: mozilla_sampler_get_backtrace_noalloc

// Fill the output buffer with the following pattern:
// "Lable 1" "\0" "Label 2" "\0" ... "Label N" "\0" "\0"
// TODO: use the unwinder instead of pseudo stack.
void mozilla_sampler_get_backtrace_noalloc(char *output, size_t outputSize)
{
  MOZ_ASSERT(outputSize >= 2);
  char *bound = output + outputSize - 2;
  output[0] = output[1] = '\0';
  PseudoStack *pseudoStack = tlsPseudoStack.get();
  if (!pseudoStack) {
    return;
  }

  volatile StackEntry *pseudoFrames = pseudoStack->mStack;
  uint32_t pseudoCount = pseudoStack->stackSize();

  for (uint32_t i = 0; i < pseudoCount; i++) {
    size_t len = strlen(pseudoFrames[i].label());
    if (output + len >= bound)
      break;
    strcpy(output, pseudoFrames[i].label());
    output += len;
    *output++ = '\0';
    *output = '\0';
  }
}
开发者ID:cliqz-oss,项目名称:browser-f,代码行数:26,代码来源:platform.cpp

示例4: InplaceTick

void TableTicker::InplaceTick(TickSample* sample)
{
  ThreadProfile& currThreadProfile = *sample->threadProfile;

  PseudoStack* stack = currThreadProfile.GetPseudoStack();
  bool recordSample = true;

  /* Don't process the PeudoStack's markers or honour jankOnly if we're
     immediately sampling the current thread. */
  if (!sample->isSamplingCurrentThread) {
    // Marker(s) come before the sample
    ProfilerMarkerLinkedList* pendingMarkersList = stack->getPendingMarkers();
    while (pendingMarkersList && pendingMarkersList->peek()) {
      ProfilerMarker* marker = pendingMarkersList->popHead();
      stack->addStoredMarker(marker);
      currThreadProfile.addTag(ProfileEntry('m', marker));
    }
    stack->updateGeneration(currThreadProfile.GetGenerationID());

    if (mJankOnly) {
      // if we are on a different event we can discard any temporary samples
      // we've kept around
      if (sLastSampledEventGeneration != sCurrentEventGeneration) {
        // XXX: we also probably want to add an entry to the profile to help
        // distinguish which samples are part of the same event. That, or record
        // the event generation in each sample
        currThreadProfile.erase();
      }
      sLastSampledEventGeneration = sCurrentEventGeneration;

      recordSample = false;
      // only record the events when we have a we haven't seen a tracer event for 100ms
      if (!sLastTracerEvent.IsNull()) {
        TimeDuration delta = sample->timestamp - sLastTracerEvent;
        if (delta.ToMilliseconds() > 100.0) {
            recordSample = true;
        }
      }
    }
  }

#if defined(USE_NS_STACKWALK) || defined(USE_EHABI_STACKWALK)
  if (mUseStackWalk) {
    doNativeBacktrace(currThreadProfile, sample);
  } else {
    doSampleStackTrace(stack, currThreadProfile, mAddLeafAddresses ? sample : nullptr);
  }
#else
  doSampleStackTrace(stack, currThreadProfile, mAddLeafAddresses ? sample : nullptr);
#endif

  if (recordSample)
    currThreadProfile.flush();

  if (!sLastTracerEvent.IsNull() && sample && currThreadProfile.IsMainThread()) {
    TimeDuration delta = sample->timestamp - sLastTracerEvent;
    currThreadProfile.addTag(ProfileEntry('r', delta.ToMilliseconds()));
  }

  if (sample) {
    TimeDuration delta = sample->timestamp - sStartTime;
    currThreadProfile.addTag(ProfileEntry('t', delta.ToMilliseconds()));
  }

  if (sLastFrameNumber != sFrameNumber) {
    currThreadProfile.addTag(ProfileEntry('f', sFrameNumber));
    sLastFrameNumber = sFrameNumber;
  }
}
开发者ID:,项目名称:,代码行数:69,代码来源:

示例5: doNativeBacktrace

void TableTicker::doNativeBacktrace(ThreadProfile &aProfile, TickSample* aSample)
{
  void *pc_array[1000];
  void *sp_array[1000];
  PCArray array = {
    pc_array,
    sp_array,
    mozilla::ArrayLength(pc_array),
    0
  };

  const mcontext_t *mcontext = &reinterpret_cast<ucontext_t *>(aSample->context)->uc_mcontext;
  mcontext_t savedContext;
  PseudoStack *pseudoStack = aProfile.GetPseudoStack();

  array.count = 0;
  // The pseudostack contains an "EnterJIT" frame whenever we enter
  // JIT code with profiling enabled; the stack pointer value points
  // the saved registers.  We use this to unwind resume unwinding
  // after encounting JIT code.
  for (uint32_t i = pseudoStack->stackSize(); i > 0; --i) {
    // The pseudostack grows towards higher indices, so we iterate
    // backwards (from callee to caller).
    volatile StackEntry &entry = pseudoStack->mStack[i - 1];
    if (!entry.js() && strcmp(entry.label(), "EnterJIT") == 0) {
      // Found JIT entry frame.  Unwind up to that point (i.e., force
      // the stack walk to stop before the block of saved registers;
      // note that it yields nondecreasing stack pointers), then restore
      // the saved state.
      uint32_t *vSP = reinterpret_cast<uint32_t*>(entry.stackAddress());

      array.count += EHABIStackWalk(*mcontext,
                                    /* stackBase = */ vSP,
                                    sp_array + array.count,
                                    pc_array + array.count,
                                    array.size - array.count);

      memset(&savedContext, 0, sizeof(savedContext));
      // See also: struct EnterJITStack in js/src/jit/arm/Trampoline-arm.cpp
      savedContext.arm_r4 = *vSP++;
      savedContext.arm_r5 = *vSP++;
      savedContext.arm_r6 = *vSP++;
      savedContext.arm_r7 = *vSP++;
      savedContext.arm_r8 = *vSP++;
      savedContext.arm_r9 = *vSP++;
      savedContext.arm_r10 = *vSP++;
      savedContext.arm_fp = *vSP++;
      savedContext.arm_lr = *vSP++;
      savedContext.arm_sp = reinterpret_cast<uint32_t>(vSP);
      savedContext.arm_pc = savedContext.arm_lr;
      mcontext = &savedContext;
    }
  }

  // Now unwind whatever's left (starting from either the last EnterJIT
  // frame or, if no EnterJIT was found, the original registers).
  array.count += EHABIStackWalk(*mcontext,
                                aProfile.GetStackTop(),
                                sp_array + array.count,
                                pc_array + array.count,
                                array.size - array.count);

  mergeNativeBacktrace(aProfile, array);
}
开发者ID:JuannyWang,项目名称:gecko-dev,代码行数:64,代码来源:TableTicker.cpp

示例6: mergeStacksIntoProfile

static
void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, NativeStack& aNativeStack)
{
  PseudoStack* pseudoStack = aProfile.GetPseudoStack();
  volatile StackEntry *pseudoFrames = pseudoStack->mStack;
  uint32_t pseudoCount = pseudoStack->stackSize();

  // Make a copy of the JS stack into a JSFrame array. This is necessary since,
  // like the native stack, the JS stack is iterated youngest-to-oldest and we
  // need to iterate oldest-to-youngest when adding entries to aProfile.

  // Synchronous sampling reports an invalid buffer generation to
  // ProfilingFrameIterator to avoid incorrectly resetting the generation of
  // sampled JIT entries inside the JS engine. See note below concerning 'J'
  // entries.
  uint32_t startBufferGen;
  if (aSample->isSamplingCurrentThread) {
    startBufferGen = UINT32_MAX;
  } else {
    startBufferGen = aProfile.bufferGeneration();
  }
  uint32_t jsCount = 0;
#ifndef SPS_STANDALONE
  JS::ProfilingFrameIterator::Frame jsFrames[1000];
  // Only walk jit stack if profiling frame iterator is turned on.
  if (pseudoStack->mRuntime && JS::IsProfilingEnabledForRuntime(pseudoStack->mRuntime)) {
    AutoWalkJSStack autoWalkJSStack;
    const uint32_t maxFrames = mozilla::ArrayLength(jsFrames);

    if (aSample && autoWalkJSStack.walkAllowed) {
      JS::ProfilingFrameIterator::RegisterState registerState;
      registerState.pc = aSample->pc;
      registerState.sp = aSample->sp;
#ifdef ENABLE_ARM_LR_SAVING
      registerState.lr = aSample->lr;
#endif

      JS::ProfilingFrameIterator jsIter(pseudoStack->mRuntime,
                                        registerState,
                                        startBufferGen);
      for (; jsCount < maxFrames && !jsIter.done(); ++jsIter) {
        // See note below regarding 'J' entries.
        if (aSample->isSamplingCurrentThread || jsIter.isAsmJS()) {
          uint32_t extracted = jsIter.extractStack(jsFrames, jsCount, maxFrames);
          jsCount += extracted;
          if (jsCount == maxFrames)
            break;
        } else {
          mozilla::Maybe<JS::ProfilingFrameIterator::Frame> frame =
            jsIter.getPhysicalFrameWithoutLabel();
          if (frame.isSome())
            jsFrames[jsCount++] = frame.value();
        }
      }
    }
  }
#endif

  // Start the sample with a root entry.
  aProfile.addTag(ProfileEntry('s', "(root)"));

  // While the pseudo-stack array is ordered oldest-to-youngest, the JS and
  // native arrays are ordered youngest-to-oldest. We must add frames to
  // aProfile oldest-to-youngest. Thus, iterate over the pseudo-stack forwards
  // and JS and native arrays backwards. Note: this means the terminating
  // condition jsIndex and nativeIndex is being < 0.
  uint32_t pseudoIndex = 0;
  int32_t jsIndex = jsCount - 1;
  int32_t nativeIndex = aNativeStack.count - 1;

  uint8_t *lastPseudoCppStackAddr = nullptr;

  // Iterate as long as there is at least one frame remaining.
  while (pseudoIndex != pseudoCount || jsIndex >= 0 || nativeIndex >= 0) {
    // There are 1 to 3 frames available. Find and add the oldest.

    uint8_t *pseudoStackAddr = nullptr;
    uint8_t *jsStackAddr = nullptr;
    uint8_t *nativeStackAddr = nullptr;

    if (pseudoIndex != pseudoCount) {
      volatile StackEntry &pseudoFrame = pseudoFrames[pseudoIndex];

      if (pseudoFrame.isCpp())
        lastPseudoCppStackAddr = (uint8_t *) pseudoFrame.stackAddress();

#ifndef SPS_STANDALONE
      // Skip any pseudo-stack JS frames which are marked isOSR
      // Pseudostack frames are marked isOSR when the JS interpreter
      // enters a jit frame on a loop edge (via on-stack-replacement,
      // or OSR).  To avoid both the pseudoframe and jit frame being
      // recorded (and showing up twice), the interpreter marks the
      // interpreter pseudostack entry with the OSR flag to ensure that
      // it doesn't get counted.
      if (pseudoFrame.isJs() && pseudoFrame.isOSR()) {
          pseudoIndex++;
          continue;
      }
#endif

//.........这里部分代码省略.........
开发者ID:valenting,项目名称:gecko-dev,代码行数:101,代码来源:GeckoSampler.cpp

示例7: InplaceTick

void GeckoSampler::InplaceTick(TickSample* sample)
{
  ThreadProfile& currThreadProfile = *sample->threadProfile;

  currThreadProfile.addTag(ProfileEntry('T', currThreadProfile.ThreadId()));

  if (sample) {
    mozilla::TimeDuration delta = sample->timestamp - sStartTime;
    currThreadProfile.addTag(ProfileEntry('t', delta.ToMilliseconds()));
  }

  PseudoStack* stack = currThreadProfile.GetPseudoStack();

#if defined(USE_NS_STACKWALK) || defined(USE_EHABI_STACKWALK) || \
    defined(USE_LUL_STACKWALK)
  if (mUseStackWalk) {
    doNativeBacktrace(currThreadProfile, sample);
  } else {
    doSampleStackTrace(currThreadProfile, sample, mAddLeafAddresses);
  }
#else
  doSampleStackTrace(currThreadProfile, sample, mAddLeafAddresses);
#endif

  // Don't process the PeudoStack's markers if we're
  // synchronously sampling the current thread.
  if (!sample->isSamplingCurrentThread) {
    ProfilerMarkerLinkedList* pendingMarkersList = stack->getPendingMarkers();
    while (pendingMarkersList && pendingMarkersList->peek()) {
      ProfilerMarker* marker = pendingMarkersList->popHead();
      currThreadProfile.addStoredMarker(marker);
      currThreadProfile.addTag(ProfileEntry('m', marker));
    }
  }

#ifndef SPS_STANDALONE
  if (sample && currThreadProfile.GetThreadResponsiveness()->HasData()) {
    mozilla::TimeDuration delta = currThreadProfile.GetThreadResponsiveness()->GetUnresponsiveDuration(sample->timestamp);
    currThreadProfile.addTag(ProfileEntry('r', delta.ToMilliseconds()));
  }
#endif

  // rssMemory is equal to 0 when we are not recording.
  if (sample && sample->rssMemory != 0) {
    currThreadProfile.addTag(ProfileEntry('R', static_cast<double>(sample->rssMemory)));
  }

  // ussMemory is equal to 0 when we are not recording.
  if (sample && sample->ussMemory != 0) {
    currThreadProfile.addTag(ProfileEntry('U', static_cast<double>(sample->ussMemory)));
  }

#if defined(XP_WIN)
  if (mProfilePower) {
    mIntelPowerGadget->TakeSample();
    currThreadProfile.addTag(ProfileEntry('p', static_cast<double>(mIntelPowerGadget->GetTotalPackagePowerInWatts())));
  }
#endif

  if (sLastFrameNumber != sFrameNumber) {
    currThreadProfile.addTag(ProfileEntry('f', sFrameNumber));
    sLastFrameNumber = sFrameNumber;
  }
}
开发者ID:valenting,项目名称:gecko-dev,代码行数:64,代码来源:GeckoSampler.cpp

示例8: GetPrimaryThreadProfile

// RUNS IN SIGHANDLER CONTEXT
void TableTicker::UnwinderTick(TickSample* sample)
{
    if (!sample->threadProfile) {
        // Platform doesn't support multithread, so use the main thread profile we created
        sample->threadProfile = GetPrimaryThreadProfile();
    }

    ThreadProfile& currThreadProfile = *sample->threadProfile;

    /* Get hold of an empty inter-thread buffer into which to park
       the ProfileEntries for this sample. */
    UnwinderThreadBuffer* utb = uwt__acquire_empty_buffer();

    /* This could fail, if no buffers are currently available, in which
       case we must give up right away.  We cannot wait for a buffer to
       become available, as that risks deadlock. */
    if (!utb)
        return;

    /* Manufacture the ProfileEntries that we will give to the unwinder
       thread, and park them in |utb|. */

    // Marker(s) come before the sample
    PseudoStack* stack = currThreadProfile.GetPseudoStack();
    for (int i = 0; stack->getMarker(i) != NULL; i++) {
        utb__addEntry( utb, ProfileEntry('m', stack->getMarker(i)) );
    }
    stack->mQueueClearMarker = true;

    bool recordSample = true;
    if (mJankOnly) {
        // if we are on a different event we can discard any temporary samples
        // we've kept around
        if (sLastSampledEventGeneration != sCurrentEventGeneration) {
            // XXX: we also probably want to add an entry to the profile to help
            // distinguish which samples are part of the same event. That, or record
            // the event generation in each sample
            currThreadProfile.erase();
        }
        sLastSampledEventGeneration = sCurrentEventGeneration;

        recordSample = false;
        // only record the events when we have a we haven't seen a tracer
        // event for 100ms
        if (!sLastTracerEvent.IsNull()) {
            TimeDuration delta = sample->timestamp - sLastTracerEvent;
            if (delta.ToMilliseconds() > 100.0) {
                recordSample = true;
            }
        }
    }

    // JRS 2012-Sept-27: this logic used to involve mUseStackWalk.
    // That should be reinstated, but for the moment, use the
    // settings in sUnwindMode and sUnwindInterval.
    // Add a native-backtrace request, or add pseudo backtrace entries,
    // or both.
    switch (sUnwindMode) {
    case UnwNATIVE: /* Native only */
        // add a "do native stack trace now" hint.  This will be actioned
        // by the unwinder thread as it processes the entries in this
        // sample.
        utb__addEntry( utb, ProfileEntry('h'/*hint*/, 'N'/*native-trace*/) );
        break;
    case UnwPSEUDO: /* Pseudo only */
        /* Add into |utb|, the pseudo backtrace entries */
        genPseudoBacktraceEntries(utb, stack, sample);
        break;
    case UnwCOMBINED: /* Both Native and Pseudo */
        utb__addEntry( utb, ProfileEntry('h'/*hint*/, 'N'/*native-trace*/) );
        genPseudoBacktraceEntries(utb, stack, sample);
        break;
    case UnwINVALID:
    default:
        MOZ_CRASH();
    }

    if (recordSample) {
        // add a "flush now" hint
        utb__addEntry( utb, ProfileEntry('h'/*hint*/, 'F'/*flush*/) );
    }

    // Add any extras
    if (!sLastTracerEvent.IsNull() && sample) {
        TimeDuration delta = sample->timestamp - sLastTracerEvent;
        utb__addEntry( utb, ProfileEntry('r', delta.ToMilliseconds()) );
    }

    if (sample) {
        TimeDuration delta = sample->timestamp - sStartTime;
        utb__addEntry( utb, ProfileEntry('t', delta.ToMilliseconds()) );
    }

    if (sLastFrameNumber != sFrameNumber) {
        utb__addEntry( utb, ProfileEntry('f', sFrameNumber) );
        sLastFrameNumber = sFrameNumber;
    }

    /* So now we have, in |utb|, the complete set of entries we want to
//.........这里部分代码省略.........
开发者ID:,项目名称:,代码行数:101,代码来源:

示例9: mergeStacksIntoProfile

static
void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, NativeStack& aNativeStack)
{
    PseudoStack* pseudoStack = aProfile.GetPseudoStack();
    volatile StackEntry *pseudoFrames = pseudoStack->mStack;
    uint32_t pseudoCount = pseudoStack->stackSize();

    // Make a copy of the JS stack into a JSFrame array. This is necessary since,
    // like the native stack, the JS stack is iterated youngest-to-oldest and we
    // need to iterate oldest-to-youngest when adding entries to aProfile.

    JSFrame jsFrames[1000];
    uint32_t jsCount = 0;
    if (aSample && pseudoStack->mRuntime) {
        JS::ProfilingFrameIterator::RegisterState registerState;
        registerState.pc = aSample->pc;
        registerState.sp = aSample->sp;
#ifdef ENABLE_ARM_LR_SAVING
        registerState.lr = aSample->lr;
#endif

        JS::ProfilingFrameIterator jsIter(pseudoStack->mRuntime, registerState);
        for (; jsCount < mozilla::ArrayLength(jsFrames) && !jsIter.done(); ++jsCount, ++jsIter) {
            jsFrames[jsCount].stackAddress = jsIter.stackAddress();
            jsFrames[jsCount].label = jsIter.label();
        }
    }

    // Start the sample with a root entry.
    aProfile.addTag(ProfileEntry('s', "(root)"));

    // While the pseudo-stack array is ordered oldest-to-youngest, the JS and
    // native arrays are ordered youngest-to-oldest. We must add frames to
    // aProfile oldest-to-youngest. Thus, iterate over the pseudo-stack forwards
    // and JS and native arrays backwards. Note: this means the terminating
    // condition jsIndex and nativeIndex is being < 0.
    uint32_t pseudoIndex = 0;
    int32_t jsIndex = jsCount - 1;
    int32_t nativeIndex = aNativeStack.count - 1;

    // Iterate as long as there is at least one frame remaining.
    while (pseudoIndex != pseudoCount || jsIndex >= 0 || nativeIndex >= 0) {
        // There are 1 to 3 frames available. Find and add the oldest. Handle pseudo
        // frames first, since there are two special cases that must be considered
        // before everything else.
        if (pseudoIndex != pseudoCount) {
            volatile StackEntry &pseudoFrame = pseudoFrames[pseudoIndex];

            // isJs pseudo-stack frames assume the stackAddress of the preceding isCpp
            // pseudo-stack frame. If we arrive at an isJs pseudo frame, we've already
            // encountered the preceding isCpp stack frame and it was oldest, we can
            // assume the isJs frame is oldest without checking other frames.
            if (pseudoFrame.isJs()) {
                addPseudoEntry(pseudoFrame, aProfile, pseudoStack, nullptr);
                pseudoIndex++;
                continue;
            }

            // Currently, only asm.js frames use the JS stack and Ion/Baseline/Interp
            // frames use the pseudo stack. In the optimized asm.js->Ion call path, no
            // isCpp frame is pushed, leading to the callstack:
            //   old | pseudo isCpp | asm.js | pseudo isJs | new
            // Since there is no interleaving isCpp pseudo frame between the asm.js
            // and isJs pseudo frame, the above isJs logic will render the callstack:
            //   old | pseudo isCpp | pseudo isJs | asm.js | new
            // which is wrong. To deal with this, a pseudo isCpp frame pushed right
            // before entering asm.js flagged with StackEntry::ASMJS. When we see this
            // flag, we first push all the asm.js frames (up to the next frame with a
            // stackAddress) before pushing the isJs frames. There is no Ion->asm.js
            // fast path, so we don't have to worry about asm.js->Ion->asm.js.
            //
            // (This and the above isJs special cases can be removed once all JS
            // execution modes switch from the pseudo stack to the JS stack.)
            if (pseudoFrame.hasFlag(StackEntry::ASMJS)) {
                void *stopStackAddress = nullptr;
                for (uint32_t i = pseudoIndex + 1; i != pseudoCount; i++) {
                    if (pseudoFrames[i].isCpp()) {
                        stopStackAddress = pseudoFrames[i].stackAddress();
                        break;
                    }
                }

                if (nativeIndex >= 0) {
                    stopStackAddress = std::max(stopStackAddress, aNativeStack.sp_array[nativeIndex]);
                }

                while (jsIndex >= 0 && jsFrames[jsIndex].stackAddress > stopStackAddress) {
                    addDynamicTag(aProfile, 'c', jsFrames[jsIndex].label);
                    jsIndex--;
                }

                pseudoIndex++;
                continue;
            }

            // Finally, consider the normal case of a plain C++ pseudo-frame.
            if ((jsIndex < 0 || pseudoFrame.stackAddress() > jsFrames[jsIndex].stackAddress) &&
                    (nativeIndex < 0 || pseudoFrame.stackAddress() > aNativeStack.sp_array[nativeIndex]))
            {
                // The (C++) pseudo-frame is the oldest.
//.........这里部分代码省略.........
开发者ID:,项目名称:,代码行数:101,代码来源:

示例10: GetThreadHandle

void TableTicker::doNativeBacktrace(ThreadProfile &aProfile, TickSample* aSample)
{
#ifndef XP_MACOSX
  uintptr_t thread = GetThreadHandle(aSample->threadProfile->GetPlatformData());
  MOZ_ASSERT(thread);
#endif
  void* pc_array[1000];
  void* sp_array[1000];
  PCArray array = {
    pc_array,
    sp_array,
    mozilla::ArrayLength(pc_array),
    0
  };

  // Start with the current function.
  StackWalkCallback(aSample->pc, aSample->sp, &array);

  uint32_t maxFrames = uint32_t(array.size - array.count);
#ifdef XP_MACOSX
  pthread_t pt = GetProfiledThread(aSample->threadProfile->GetPlatformData());
  void *stackEnd = reinterpret_cast<void*>(-1);
  if (pt)
    stackEnd = static_cast<char*>(pthread_get_stackaddr_np(pt));
  nsresult rv = NS_OK;
  if (aSample->fp >= aSample->sp && aSample->fp <= stackEnd)
    rv = FramePointerStackWalk(StackWalkCallback, /* skipFrames */ 0,
                               maxFrames, &array,
                               reinterpret_cast<void**>(aSample->fp), stackEnd);
#else
  void *platformData = nullptr;
#ifdef XP_WIN
  platformData = aSample->context;
#endif // XP_WIN

  nsresult rv = NS_StackWalk(StackWalkCallback, /* skipFrames */ 0, maxFrames,
                             &array, thread, platformData);
#endif
  if (NS_SUCCEEDED(rv)) {
    aProfile.addTag(ProfileEntry('s', "(root)"));

    PseudoStack* stack = aProfile.GetPseudoStack();
    uint32_t pseudoStackPos = 0;

    /* We have two stacks, the native C stack we extracted from unwinding,
     * and the pseudostack we managed during execution. We want to consolidate
     * the two in order. We do so by merging using the approximate stack address
     * when each entry was push. When pushing JS entry we may not now the stack
     * address in which case we have a NULL stack address in which case we assume
     * that it follows immediatly the previous element.
     *
     *  C Stack | Address    --  Pseudo Stack | Address
     *  main()  | 0x100          run_js()     | 0x40
     *  start() | 0x80           jsCanvas()   | NULL
     *  timer() | 0x50           drawLine()   | NULL
     *  azure() | 0x10
     *
     * Merged: main(), start(), timer(), run_js(), jsCanvas(), drawLine(), azure()
     */
    // i is the index in C stack starting at main and decreasing
    // pseudoStackPos is the position in the Pseudo stack starting
    // at the first frame (run_js in the example) and increasing.
    for (size_t i = array.count; i > 0; --i) {
      while (pseudoStackPos < stack->stackSize()) {
        volatile StackEntry& entry = stack->mStack[pseudoStackPos];

        if (entry.stackAddress() < array.sp_array[i-1] && entry.stackAddress())
          break;

        addProfileEntry(entry, aProfile, stack, array.array[0]);
        pseudoStackPos++;
      }

      aProfile.addTag(ProfileEntry('l', (void*)array.array[i-1]));
    }
  }
}
开发者ID:,项目名称:,代码行数:77,代码来源:


注:本文中的PseudoStack类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。