Bug 1639153 - Part 4: Untie frame iteration from Frame::tls. r=lth
☠☠ backed out by 1fc282e54b7a ☠ ☠
authorDmitry Bezhetskov <dbezhetskov@igalia.com>
Thu, 27 Aug 2020 10:30:46 +0000
changeset 548288 f2e486f1be1760e1751cf50acea1ab50cb3cfa90
parent 548287 b79c89e6ac82e947d6805ce7fb4ee52f28c55a5a
child 548289 62480de389ffba353998de24760993b2e1531232
push id37776
push userbtara@mozilla.com
push dateFri, 11 Sep 2020 15:10:42 +0000
treeherdermozilla-central@b133e2d673e8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslth
bugs1639153
milestone82.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 1639153 - Part 4: Untie frame iteration from Frame::tls. r=lth Here we replace usage of Frame::tls in frame iteration with GetNearestEffectiveTls. We also maintain current tls for frame iteration object to not to call GetNearestEffectiveTls everytime. Differential Revision: https://phabricator.services.mozilla.com/D83045 Depends on D83044
js/src/jit/MacroAssembler.cpp
js/src/jit/MacroAssembler.h
js/src/wasm/WasmFrameIter.cpp
js/src/wasm/WasmFrameIter.h
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -4527,24 +4527,27 @@ void AutoGenericRegisterScope<RegisterTy
   released_ = false;
   const RegisterType& reg = *dynamic_cast<RegisterType*>(this);
   masm_.debugTrackedRegisters_.add(reg);
 }
 
 template void AutoGenericRegisterScope<Register>::reacquire();
 template void AutoGenericRegisterScope<FloatRegister>::reacquire();
 
-wasm::TlsData* ExtractCallerTlsFromFrameWithTls(wasm::Frame* fp) {
-  return *reinterpret_cast<wasm::TlsData**>(
-      reinterpret_cast<uint8_t*>(fp) + sizeof(wasm::Frame) + ShadowStackSpace +
-      wasm::FrameWithTls::callerTLSOffset());
-}
-
-wasm::TlsData* ExtractCalleeTlsFromFrameWithTls(wasm::Frame* fp) {
-  return *reinterpret_cast<wasm::TlsData**>(
-      reinterpret_cast<uint8_t*>(fp) + sizeof(wasm::Frame) + ShadowStackSpace +
-      wasm::FrameWithTls::calleeTLSOffset());
-}
-
 #endif  // DEBUG
 
 }  // namespace jit
+
+namespace wasm {
+TlsData* ExtractCallerTlsFromFrameWithTls(Frame* fp) {
+  return *reinterpret_cast<TlsData**>(reinterpret_cast<uint8_t*>(fp) +
+                                      sizeof(Frame) + ShadowStackSpace +
+                                      FrameWithTls::callerTLSOffset());
+}
+
+TlsData* ExtractCalleeTlsFromFrameWithTls(Frame* fp) {
+  return *reinterpret_cast<TlsData**>(reinterpret_cast<uint8_t*>(fp) +
+                                      sizeof(Frame) + ShadowStackSpace +
+                                      FrameWithTls::calleeTLSOffset());
+}
+}  // namespace wasm
+
 }  // namespace js
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -4284,15 +4284,18 @@ class WasmABIArgGenerator : public ABIAr
 
 template <class VecT>
 class WasmABIArgIter : public ABIArgIterBase<VecT, WasmABIArgGenerator> {
  public:
   explicit WasmABIArgIter(const VecT& types)
       : ABIArgIterBase<VecT, WasmABIArgGenerator>(types) {}
 };
 
-wasm::TlsData* ExtractCalleeTlsFromFrameWithTls(wasm::Frame* fp);
-wasm::TlsData* ExtractCallerTlsFromFrameWithTls(wasm::Frame* fp);
-
 }  // namespace jit
+
+namespace wasm {
+TlsData* ExtractCalleeTlsFromFrameWithTls(Frame* fp);
+TlsData* ExtractCallerTlsFromFrameWithTls(Frame* fp);
+}  // namespace wasm
+
 }  // namespace js
 
 #endif /* jit_MacroAssembler_h */
--- a/js/src/wasm/WasmFrameIter.cpp
+++ b/js/src/wasm/WasmFrameIter.cpp
@@ -35,34 +35,36 @@ using mozilla::Maybe;
 // WasmFrameIter implementation
 
 WasmFrameIter::WasmFrameIter(JitActivation* activation, wasm::Frame* fp)
     : activation_(activation),
       code_(nullptr),
       codeRange_(nullptr),
       lineOrBytecode_(0),
       fp_(fp ? fp : activation->wasmExitFP()),
+      tls_(nullptr),
       unwoundIonCallerFP_(nullptr),
       unwoundIonFrameType_(jit::FrameType(-1)),
       unwind_(Unwind::False),
       unwoundAddressOfReturnAddress_(nullptr),
       resumePCinCurrentFrame_(nullptr) {
   MOZ_ASSERT(fp_);
+  tls_ = GetNearestEffectiveTls(fp_);
 
   // When the stack is captured during a trap (viz., to create the .stack
   // for an Error object), use the pc/bytecode information captured by the
   // signal handler in the runtime. Take care not to use this trap unwind
   // state for wasm frames in the middle of a JitActivation, i.e., wasm frames
   // that called into JIT frames before the trap.
 
   if (activation->isWasmTrapping() && fp_ == activation->wasmExitFP()) {
     const TrapData& trapData = activation->wasmTrapData();
     void* unwoundPC = trapData.unwoundPC;
 
-    code_ = &fp_->instance()->code();
+    code_ = &tls_->instance->code();
     MOZ_ASSERT(code_ == LookupCode(unwoundPC));
 
     codeRange_ = code_->lookupFuncRange(unwoundPC);
     MOZ_ASSERT(codeRange_);
 
     lineOrBytecode_ = trapData.bytecodeOffset;
 
     MOZ_ASSERT(!done());
@@ -189,22 +191,28 @@ void WasmFrameIter::popFrame() {
       activation_->setJSExitFP(unwoundIonCallerFP());
       unwoundAddressOfReturnAddress_ = prevFP->addressOfReturnAddress();
     }
 
     MOZ_ASSERT(done());
     return;
   }
 
-  MOZ_ASSERT(code_ == &fp_->instance()->code());
   MOZ_ASSERT(codeRange_->kind() == CodeRange::Function);
 
   const CallSite* callsite = code_->lookupCallSite(returnAddress);
   MOZ_ASSERT(callsite);
 
+  if (callsite->mightBeCrossInstance()) {
+    tls_ = ExtractCallerTlsFromFrameWithTls(prevFP);
+  }
+
+  MOZ_ASSERT(code_ == &fp_->instance()->code());
+  MOZ_ASSERT(fp_->instance() == tls()->instance);
+
   lineOrBytecode_ = callsite->lineOrBytecode();
 
   MOZ_ASSERT(!done());
 }
 
 const char* WasmFrameIter::filename() const {
   MOZ_ASSERT(!done());
   return code_->metadata().filename.get();
@@ -267,17 +275,17 @@ unsigned WasmFrameIter::computeLine(uint
   if (column) {
     *column = codeRange_->funcIndex() | ColumnBit;
   }
   return lineOrBytecode_;
 }
 
 Instance* WasmFrameIter::instance() const {
   MOZ_ASSERT(!done());
-  return fp_->instance();
+  return tls_->instance;
 }
 
 void** WasmFrameIter::unwoundAddressOfReturnAddress() const {
   MOZ_ASSERT(done());
   MOZ_ASSERT(unwind_ == Unwind::True);
   MOZ_ASSERT(unwoundAddressOfReturnAddress_);
   return unwoundAddressOfReturnAddress_;
 }
--- a/js/src/wasm/WasmFrameIter.h
+++ b/js/src/wasm/WasmFrameIter.h
@@ -60,16 +60,17 @@ class WasmFrameIter {
   static constexpr uint32_t ColumnBit = 1u << 31;
 
  private:
   jit::JitActivation* activation_;
   const Code* code_;
   const CodeRange* codeRange_;
   unsigned lineOrBytecode_;
   Frame* fp_;
+  TlsData* tls_;
   uint8_t* unwoundIonCallerFP_;
   jit::FrameType unwoundIonFrameType_;
   Unwind unwind_;
   void** unwoundAddressOfReturnAddress_;
   uint8_t* resumePCinCurrentFrame_;
 
   void popFrame();
 
@@ -90,16 +91,17 @@ class WasmFrameIter {
   const CodeRange* codeRange() const { return codeRange_; }
   Instance* instance() const;
   void** unwoundAddressOfReturnAddress() const;
   bool debugEnabled() const;
   DebugFrame* debugFrame() const;
   jit::FrameType unwoundIonFrameType() const;
   uint8_t* unwoundIonCallerFP() const { return unwoundIonCallerFP_; }
   Frame* frame() const { return fp_; }
+  TlsData* tls() const { return tls_; }
 
   // Returns the address of the next instruction that will execute in this
   // frame, once control returns to this frame.
   uint8_t* resumePCinCurrentFrame() const;
 };
 
 enum class SymbolicAddress;