namespace mirror { class Object;
} // namespace mirror
class ArtMethod; class ShadowFrame; template <typename T> class StackReference;
// The managed stack is used to record fragments of managed code stacks. Managed code stacks // may either be shadow frames or lists of frames using fixed frame sizes. Transition records are // necessary for transitions between code using different frame layouts and transitions into native // code. // // Each ManagedStack fragment may contain either a quick code's sp or address to a shadow frame. // It is an invariant that both are never set at the same time. // // Each fragment may contain a mini stack, more than one call frame. For quick code, we extract the // call's frame size (known a priori) to obtain the caller's sp. The walk for this fragment // terminates when a potential caller's sp contains null (instead of a valid ArtMethod*). A // null-valued sp is set up by a quick code stub. For shadow frames, we chase the link_ pointer // until null. Once a mini stack is completely walked, we move onto the next fragment. // // The topmost fragment is always held in the thread's TLS region. class PACKED(4) ManagedStack { public: static size_t constexpr kTaggedJniSpMask = 0x3;
private: void PushManagedStackFragment(ManagedStack* fragment) { // Copy this top fragment into given fragment.
memcpy(fragment, this, sizeof(ManagedStack)); // Clear this fragment, which has become the top.
memset(this, 0, sizeof(ManagedStack)); // Link our top fragment onto the given fragment.
link_ = fragment;
}
void PopManagedStackFragment(const ManagedStack& fragment) {
DCHECK(&fragment == link_); // Copy this given fragment back to the top.
memcpy(this, &fragment, sizeof(ManagedStack));
}
// Encodes the top quick frame (which must be at least 4-byte aligned) // and a flag that marks the GenericJNI trampoline. class TaggedTopQuickFrame { public: static TaggedTopQuickFrame CreateNotTagged(ArtMethod** sp) {
DCHECK_ALIGNED(sp, 4u); return TaggedTopQuickFrame(reinterpret_cast<uintptr_t>(sp));
}
// Get SP known to be not tagged and non-null.
ArtMethod** GetSpKnownNotTagged() const {
DCHECK(!GetGenericJniTag() && !GetJitJniTag());
DCHECK_NE(tagged_sp_, 0u); returnreinterpret_cast<ArtMethod**>(tagged_sp_);
}
// For PushManagedStackFragment and PopManagedStackFragment. friendclass Thread;
};
// Scoped class to manage pushing and popping ShadowFrame on the stack that ensures that a pushed // shadow frame is always popped when the scope is exited. // // Example usage: // ManagedStack fragment; // ScopedManagedStackFragment smsf(self, &fragment); // // ... code that uses the new stack fragment ... // // fragment is automatically popped when smsf goes out of scope. class ScopedManagedStackFragment { public:
ScopedManagedStackFragment(Thread* self, ManagedStack* fragment);
~ScopedManagedStackFragment();
// Scoped class to manage pushing and popping ShadowFrame on the stack that ensures that a pushed // shadow frame is always popped when the scope is exited. // // Example usage: // ShadowFrame* shadow_frame = ...; // ScopedShadowFrame ssf(self, shadow_frame); // // ... code that uses the shadow frame ... // // shadow_frame is automatically popped when ssf goes out of scope. class ScopedShadowFrame { public:
ScopedShadowFrame(Thread* self, ShadowFrame* sf);
~ScopedShadowFrame();
private:
Thread* self_;
ShadowFrame* sf_;
};
} // namespace art
#endif// ART_RUNTIME_MANAGED_STACK_H_
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.0 Sekunden
(vorverarbeitet am 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.