Bug 1552154 part 4 - Stop using pc-to-native map for BaselineScript::approximatePcForNativeAddress. r=tcampbell
authorJan de Mooij <jdemooij@mozilla.com>
Sat, 10 Aug 2019 10:21:00 +0000
changeset 487325 703a39b468df1440a5ba8967ddbf67909c68f4b0
parent 487324 941b29575f6ab24bca3c8adb87448cf0238260f1
child 487326 e481b4ed77849bd73ca3fb6a2b7828d6fcbab94e
push id113869
push userncsoregi@mozilla.com
push dateSat, 10 Aug 2019 21:42:30 +0000
treeherdermozilla-inbound@5cd7526ffbc3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1552154
milestone70.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1552154 part 4 - Stop using pc-to-native map for BaselineScript::approximatePcForNativeAddress. r=tcampbell Differential Revision: https://phabricator.services.mozilla.com/D40947
js/src/jit/BaselineJIT.cpp
js/src/jit/BaselineJIT.h
--- a/js/src/jit/BaselineJIT.cpp
+++ b/js/src/jit/BaselineJIT.cpp
@@ -774,66 +774,33 @@ uint8_t* BaselineScript::maybeNativeCode
 
 jsbytecode* BaselineScript::approximatePcForNativeAddress(
     JSScript* script, uint8_t* nativeAddress) {
   MOZ_ASSERT(script->baselineScript() == this);
   MOZ_ASSERT(containsCodeAddress(nativeAddress));
 
   uint32_t nativeOffset = nativeAddress - method_->raw();
 
-  // The native code address can occur before the start of ops. Associate
-  // those with start of bytecode.
-  if (nativeOffset < pcMappingIndexEntry(0).nativeOffset) {
-    return script->code();
-  }
+  // Use the RetAddrEntry list (sorted on pc and return address) to look for the
+  // first pc that has a return address >= nativeOffset. This isn't perfect but
+  // it's a reasonable approximation for the profiler because most non-trivial
+  // bytecode ops have a RetAddrEntry.
 
-  // Find corresponding PCMappingIndexEntry for native offset. They are in
-  // ascedending order with the start of one entry being the end of the
-  // previous entry. Find first entry where nativeOffset < endOffset.
-  uint32_t i = 0;
-  for (; (i + 1) < numPCMappingIndexEntries(); i++) {
-    uint32_t endOffset = pcMappingIndexEntry(i + 1).nativeOffset;
-    if (nativeOffset < endOffset) {
-      break;
+  for (const RetAddrEntry& entry : retAddrEntries()) {
+    uint32_t retOffset = entry.returnOffset().offset();
+    if (retOffset >= nativeOffset) {
+      return script->offsetToPC(entry.pcOffset());
     }
   }
 
-  PCMappingIndexEntry& entry = pcMappingIndexEntry(i);
-  MOZ_ASSERT(nativeOffset >= entry.nativeOffset);
-
-  CompactBufferReader reader(pcMappingReader(i));
-  MOZ_ASSERT(reader.more());
-
-  jsbytecode* curPC = script->offsetToPC(entry.pcOffset);
-  uint32_t curNativeOffset = entry.nativeOffset;
-  MOZ_ASSERT(script->containsPC(curPC));
-
-  jsbytecode* lastPC = curPC;
-  while (reader.more()) {
-    // If the high bit is set, the native offset relative to the
-    // previous pc != 0 and comes next.
-    uint8_t b = reader.readByte();
-    if (b & 0x80) {
-      curNativeOffset += reader.readUnsigned();
-    }
-
-    // Return the last PC that matched nativeOffset. Some bytecode
-    // generate no native code (e.g., constant-pushing bytecode like
-    // JSOP_INT8), and so their entries share the same nativeOffset as the
-    // next op that does generate code.
-    if (curNativeOffset > nativeOffset) {
-      return lastPC;
-    }
-
-    lastPC = curPC;
-    curPC += GetBytecodeLength(curPC);
-  }
-
-  // Associate all addresses at end of PCMappingIndexEntry with lastPC.
-  return lastPC;
+  // Return the last entry's pc. Every BaselineScript has at least one
+  // RetAddrEntry for the prologue stack overflow check.
+  MOZ_ASSERT(retAddrEntries().size() > 0);
+  const RetAddrEntry& lastEntry = retAddrEntries()[retAddrEntries().size() - 1];
+  return script->offsetToPC(lastEntry.pcOffset());
 }
 
 void BaselineScript::toggleDebugTraps(JSScript* script, jsbytecode* pc) {
   MOZ_ASSERT(script->baselineScript() == this);
 
   // Only scripts compiled for debug mode have toggled calls.
   if (!hasDebugInstrumentation()) {
     return;
--- a/js/src/jit/BaselineJIT.h
+++ b/js/src/jit/BaselineJIT.h
@@ -416,18 +416,18 @@ struct BaselineScript final {
   uint8_t* nativeCodeForPC(JSScript* script, jsbytecode* pc,
                            PCMappingSlotInfo* slotInfo) {
     uint8_t* native = maybeNativeCodeForPC(script, pc, slotInfo);
     MOZ_ASSERT(native);
     return native;
   }
 
   // Return the bytecode offset for a given native code address. Be careful
-  // when using this method: we don't emit code for some bytecode ops, so
-  // the result may not be accurate.
+  // when using this method: it's an approximation and not guaranteed to be the
+  // correct pc.
   jsbytecode* approximatePcForNativeAddress(JSScript* script,
                                             uint8_t* nativeAddress);
 
   // Toggle debug traps (used for breakpoints and step mode) in the script.
   // If |pc| is nullptr, toggle traps for all ops in the script. Else, only
   // toggle traps at |pc|.
   void toggleDebugTraps(JSScript* script, jsbytecode* pc);