Skip to content

Require SwiftASTContextReader to be valid at all times #1440

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions lldb/include/lldb/Core/SwiftASTContextReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,26 @@ struct ScopedSharedMutexReader {
/// or even separate scratch contexts for each lldb::Module. But it
/// will only do this if no client holds on to a read lock on \b
/// m_scratch_typesystem_lock.
struct SwiftASTContextReader : ScopedSharedMutexReader {
SwiftASTContextForExpressions *m_ptr = nullptr;
SwiftASTContextReader() : ScopedSharedMutexReader(nullptr) {}
SwiftASTContextReader(SharedMutex &mutex, SwiftASTContextForExpressions *ctx)
: ScopedSharedMutexReader(&mutex), m_ptr(ctx) {}
class SwiftASTContextReader : ScopedSharedMutexReader {
SwiftASTContextForExpressions *m_ptr;

public:
SwiftASTContextReader(SharedMutex &mutex, SwiftASTContextForExpressions &ctx)
: ScopedSharedMutexReader(&mutex), m_ptr(&ctx) {
assert(m_ptr && "invalid context");
}

SwiftASTContextReader(const SwiftASTContextReader &copy)
: ScopedSharedMutexReader(copy.m_mutex), m_ptr(copy.m_ptr) {}
SwiftASTContextForExpressions *get() { return m_ptr; }
operator bool() const { return m_ptr; }
SwiftASTContextForExpressions *operator->() { return m_ptr; }
SwiftASTContextForExpressions &operator*() { return *m_ptr; }

SwiftASTContextForExpressions *get() {
assert(m_ptr && "invalid context");
return m_ptr;
}

SwiftASTContextForExpressions *operator->() { return get(); }

SwiftASTContextForExpressions &operator*() { return *get(); }
};

/// An RAII object that just acquires the reader lock.
Expand Down
2 changes: 1 addition & 1 deletion lldb/include/lldb/Core/ValueObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ class ValueObject : public UserID {

virtual bool HasSyntheticValue();

SwiftASTContextReader GetScratchSwiftASTContext();
llvm::Optional<SwiftASTContextReader> GetScratchSwiftASTContext();

virtual bool IsSynthetic() { return false; }

Expand Down
2 changes: 1 addition & 1 deletion lldb/include/lldb/Target/Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -1127,7 +1127,7 @@ class Target : public std::enable_shared_from_this<Target>,
return m_scratch_typesystem_lock;
}

SwiftASTContextReader
llvm::Optional<SwiftASTContextReader>
GetScratchSwiftASTContext(Status &error, ExecutionContextScope &exe_scope,
bool create_on_demand = true);

Expand Down
4 changes: 2 additions & 2 deletions lldb/source/Core/ValueObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1697,10 +1697,10 @@ LanguageType ValueObject::GetObjectRuntimeLanguage() {
return lldb::eLanguageTypeUnknown;
}

SwiftASTContextReader ValueObject::GetScratchSwiftASTContext() {
llvm::Optional<SwiftASTContextReader> ValueObject::GetScratchSwiftASTContext() {
lldb::TargetSP target_sp(GetTargetSP());
if (!target_sp)
return {};
return llvm::None;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we could leave this as is, too.

Status error;
ExecutionContext ctx = GetExecutionContextRef().Lock(false);
auto *exe_scope = ctx.GetBestExecutionContextScope();
Expand Down
4 changes: 3 additions & 1 deletion lldb/source/Core/ValueObjectDynamicValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -433,5 +433,7 @@ bool ValueObjectDynamicValue::DynamicValueTypeInfoNeedsUpdate() {
return false;

auto *cached_ctx = m_value.GetCompilerType().GetTypeSystem();
return cached_ctx == GetScratchSwiftASTContext().get();
llvm::Optional<SwiftASTContextReader> scratch_ctx =
GetScratchSwiftASTContext();
return scratch_ctx ? (cached_ctx == scratch_ctx->get()) : !cached_ctx;
}
6 changes: 3 additions & 3 deletions lldb/source/Expression/Materializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -927,9 +927,9 @@ class EntityResultVariable : public Materializer::Entity {

if (m_type.GetMinimumLanguage() == lldb::eLanguageTypeSwift) {
Status status;
auto type_system =
target_sp->GetScratchSwiftASTContext(status, *exe_scope).get();
if (type_system == nullptr) {
llvm::Optional<SwiftASTContextReader> maybe_type_system =
target_sp->GetScratchSwiftASTContext(status, *exe_scope);
if (!maybe_type_system) {
err.SetErrorStringWithFormat("Couldn't dematerialize a result variable: "
"couldn't get the corresponding type "
"system: %s", status.AsCString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,11 @@ SwiftExpressionParser::SwiftExpressionParser(

if (target_sp) {
Status error;
m_swift_ast_context = std::make_unique<SwiftASTContextReader>(
target_sp->GetScratchSwiftASTContext(error, *exe_scope, true));
llvm::Optional<SwiftASTContextReader> scratch_ctx =
target_sp->GetScratchSwiftASTContext(error, *exe_scope, true);
if (scratch_ctx)
m_swift_ast_context =
std::make_unique<SwiftASTContextReader>(scratch_ctx.getValue());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,13 @@ void SwiftUserExpression::ScanContext(ExecutionContext &exe_ctx, Status &err) {

// Make sure the target's SwiftASTContext has been setup before doing any
// Swift name lookups.
auto swift_ast_ctx = m_target->GetScratchSwiftASTContext(err, *frame);
if (!swift_ast_ctx) {
llvm::Optional<SwiftASTContextReader> maybe_swift_ast_ctx =
m_target->GetScratchSwiftASTContext(err, *frame);
if (!maybe_swift_ast_ctx) {
LLDB_LOG(log, " [SUE::SC] NULL Swift AST Context");
return;
}
SwiftASTContext *swift_ast_ctx = maybe_swift_ast_ctx->get();

if (!swift_ast_ctx->GetClangImporter()) {
LLDB_LOG(log, " [SUE::SC] Swift AST Context has no Clang importer");
Expand Down
12 changes: 6 additions & 6 deletions lldb/source/Plugins/Language/Swift/SwiftHashedContainer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,13 +294,13 @@ HashedCollectionConfig::StorageObjectAtAddress(
// same address.
Status error;
ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
auto reader =
llvm::Optional<SwiftASTContextReader> reader =
process_sp->GetTarget().GetScratchSwiftASTContext(error, *exe_scope);
SwiftASTContext *ast_ctx = reader.get();
if (!ast_ctx)
if (!reader)
return nullptr;
if (error.Fail())
return nullptr;
SwiftASTContext *ast_ctx = reader->get();

CompilerType rawStorage_type =
ast_ctx->GetTypeFromMangledTypename(m_nativeStorageRoot_mangled);
Expand Down Expand Up @@ -445,10 +445,10 @@ NativeHashedStorageHandler::NativeHashedStorageHandler(
m_value_stride = value_type_stride ? *value_type_stride : 0;
if (TypeSystemSwift *swift_ast =
llvm::dyn_cast_or_null<TypeSystemSwift>(key_type.GetTypeSystem())) {
auto scratch_ctx_reader = nativeStorage_sp->GetScratchSwiftASTContext();
auto scratch_ctx = scratch_ctx_reader.get();
if (!scratch_ctx)
llvm::Optional<SwiftASTContextReader> scratch_ctx_reader = nativeStorage_sp->GetScratchSwiftASTContext();
if (!scratch_ctx_reader)
return;
SwiftASTContext *scratch_ctx = scratch_ctx_reader->get();
auto *runtime = SwiftLanguageRuntime::Get(m_process);
if (!runtime)
return;
Expand Down
16 changes: 10 additions & 6 deletions lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1013,9 +1013,11 @@ std::unique_ptr<Language::TypeScavenger> SwiftLanguage::GetTypeScavenger() {
if (target) {
const bool create_on_demand = false;
Status error;
auto ast_ctx = target->GetScratchSwiftASTContext(
error, *exe_scope, create_on_demand);
if (ast_ctx) {
llvm::Optional<SwiftASTContextReader> maybe_ast_ctx =
target->GetScratchSwiftASTContext(error, *exe_scope,
create_on_demand);
if (maybe_ast_ctx) {
SwiftASTContext *ast_ctx = maybe_ast_ctx->get();
ConstString cs_input{input};
Mangled mangled(cs_input);
if (mangled.GuessLanguage() == eLanguageTypeSwift) {
Expand Down Expand Up @@ -1071,9 +1073,11 @@ std::unique_ptr<Language::TypeScavenger> SwiftLanguage::GetTypeScavenger() {
Target *target = exe_scope->CalculateTarget().get();
const bool create_on_demand = false;
Status error;
auto ast_ctx = target->GetScratchSwiftASTContext(error, *exe_scope,
create_on_demand);
if (ast_ctx) {
llvm::Optional<SwiftASTContextReader> maybe_ast_ctx =
target->GetScratchSwiftASTContext(error, *exe_scope,
create_on_demand);
if (maybe_ast_ctx) {
SwiftASTContext *ast_ctx = maybe_ast_ctx->get();
auto iter = ast_ctx->GetModuleCache().begin(),
end = ast_ctx->GetModuleCache().end();

Expand Down
16 changes: 10 additions & 6 deletions lldb/source/Target/SwiftLanguageRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -945,8 +945,10 @@ void SwiftLanguageRuntime::FindFunctionPointersInCall(
Status error;
Target &target = frame.GetThread()->GetProcess()->GetTarget();
ExecutionContext exe_ctx(frame);
auto swift_ast = target.GetScratchSwiftASTContext(error, frame);
if (swift_ast) {
llvm::Optional<SwiftASTContextReader> maybe_swift_ast =
target.GetScratchSwiftASTContext(error, frame);
if (maybe_swift_ast) {
SwiftASTContext *swift_ast = maybe_swift_ast->get();
CompilerType function_type = swift_ast->GetTypeFromMangledTypename(
mangled_name.GetMangledName());
if (error.Success()) {
Expand Down Expand Up @@ -1152,9 +1154,11 @@ SwiftLanguageRuntime::CalculateErrorValue(StackFrameSP frame_sp,
if (!exe_scope)
return error_valobj_sp;

auto ast_context = target->GetScratchSwiftASTContext(error, *frame_sp);
if (!ast_context || error.Fail())
llvm::Optional<SwiftASTContextReader> maybe_ast_context =
target->GetScratchSwiftASTContext(error, *frame_sp);
if (!maybe_ast_context || error.Fail())
return error_valobj_sp;
SwiftASTContext *ast_context = maybe_ast_context->get();

lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(
arg0->GetScalar().GetBytes(), arg0->GetScalar().GetByteSize()));
Expand Down Expand Up @@ -1483,9 +1487,9 @@ SwiftLanguageRuntimeImpl::GetBridgedSyntheticChildProvider(
ProjectionSyntheticChildren::TypeProjectionUP type_projection(
new ProjectionSyntheticChildren::TypeProjectionUP::element_type());

if (auto swift_ast_ctx = valobj.GetScratchSwiftASTContext()) {
if (auto maybe_swift_ast_ctx = valobj.GetScratchSwiftASTContext()) {
CompilerType swift_type =
swift_ast_ctx->GetTypeFromMangledTypename(type_name);
maybe_swift_ast_ctx->get()->GetTypeFromMangledTypename(type_name);

if (swift_type.IsValid()) {
ExecutionContext exe_ctx(m_process);
Expand Down
37 changes: 24 additions & 13 deletions lldb/source/Target/SwiftLanguageRuntimeDynamicTypeResolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -513,18 +513,20 @@ SwiftLanguageRuntime::MetadataPromise::FulfillTypePromise(Status *error) {
if (m_compiler_type.hasValue())
return m_compiler_type.getValue();

auto swift_ast_ctx = m_for_object_sp->GetScratchSwiftASTContext();
if (!swift_ast_ctx) {
llvm::Optional<SwiftASTContextReader> maybe_swift_ast_ctx =
m_for_object_sp->GetScratchSwiftASTContext();
if (!maybe_swift_ast_ctx) {
error->SetErrorString("couldn't get Swift scratch context");
return CompilerType();
}
SwiftASTContext *swift_ast_ctx = maybe_swift_ast_ctx->get();
auto &remote_ast = m_swift_runtime.GetRemoteASTContext(*swift_ast_ctx);
swift::remoteAST::Result<swift::Type> result =
remote_ast.getTypeForRemoteTypeMetadata(
swift::remote::RemoteAddress(m_metadata_location));

if (result) {
m_compiler_type = {swift_ast_ctx.get(), result.getValue().getPointer()};
m_compiler_type = {swift_ast_ctx, result.getValue().getPointer()};
if (log)
log->Printf("[MetadataPromise] result is type %s",
m_compiler_type->GetTypeName().AsCString());
Expand All @@ -543,10 +545,13 @@ SwiftLanguageRuntime::MetadataPromise::FulfillTypePromise(Status *error) {
SwiftLanguageRuntime::MetadataPromiseSP
SwiftLanguageRuntimeImpl::GetMetadataPromise(lldb::addr_t addr,
ValueObject &for_object) {
auto swift_ast_ctx = for_object.GetScratchSwiftASTContext();
if (!swift_ast_ctx || swift_ast_ctx->HasFatalErrors())
llvm::Optional<SwiftASTContextReader> maybe_swift_ast_ctx =
for_object.GetScratchSwiftASTContext();
if (!maybe_swift_ast_ctx)
return nullptr;
SwiftASTContext *swift_ast_ctx = maybe_swift_ast_ctx->get();
if (swift_ast_ctx->HasFatalErrors())
return nullptr;

if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
return nullptr;

Expand Down Expand Up @@ -1038,9 +1043,11 @@ SwiftLanguageRuntimeImpl::DoArchetypeBindingForType(StackFrame &stack_frame,
auto &target = m_process.GetTarget();
assert(IsScratchContextLocked(target) &&
"Swift scratch context not locked ahead of archetype binding");
auto scratch_ctx = target.GetScratchSwiftASTContext(error, stack_frame);
if (!scratch_ctx)
llvm::Optional<SwiftASTContextReader> maybe_scratch_ctx =
target.GetScratchSwiftASTContext(error, stack_frame);
if (!maybe_scratch_ctx)
return base_type;
SwiftASTContext *scratch_ctx = maybe_scratch_ctx->get();
base_type = scratch_ctx->ImportType(base_type, error);

if (base_type.GetTypeInfo() & lldb::eTypeIsSwift) {
Expand Down Expand Up @@ -1425,11 +1432,13 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType(
// Import the remangled dynamic name into the scratch context.
assert(IsScratchContextLocked(in_value.GetTargetSP()) &&
"Swift scratch context not locked ahead of dynamic type resolution");
auto scratch_ctx = in_value.GetScratchSwiftASTContext();
if (!scratch_ctx)
llvm::Optional<SwiftASTContextReader> maybe_scratch_ctx =
in_value.GetScratchSwiftASTContext();
if (!maybe_scratch_ctx)
return false;
CompilerType swift_type =
scratch_ctx->GetTypeFromMangledTypename(ConstString(remangled));
maybe_scratch_ctx->get()->GetTypeFromMangledTypename(
ConstString(remangled));

// Roll back the ObjC dynamic type resolution.
if (!swift_type)
Expand Down Expand Up @@ -1483,9 +1492,11 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress(
// use the scratch context where such operations are legal and safe.
assert(IsScratchContextLocked(in_value.GetTargetSP()) &&
"Swift scratch context not locked ahead of dynamic type resolution");
auto scratch_ctx = in_value.GetScratchSwiftASTContext();
if (!scratch_ctx)
llvm::Optional<SwiftASTContextReader> maybe_scratch_ctx =
in_value.GetScratchSwiftASTContext();
if (!maybe_scratch_ctx)
return false;
SwiftASTContextForExpressions *scratch_ctx = maybe_scratch_ctx->get();

auto retry_once = [&]() {
// Retry exactly once using the per-module fallback scratch context.
Expand Down
13 changes: 8 additions & 5 deletions lldb/source/Target/Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2336,11 +2336,12 @@ Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) {
SwiftPersistentExpressionState *
Target::GetSwiftPersistentExpressionState(ExecutionContextScope &exe_scope) {
Status error;
auto swift_ast_context = GetScratchSwiftASTContext(error, exe_scope, true);
if (!swift_ast_context)
auto maybe_swift_ast_context =
GetScratchSwiftASTContext(error, exe_scope, true);
if (!maybe_swift_ast_context)
return nullptr;
return (SwiftPersistentExpressionState *)
swift_ast_context->GetPersistentExpressionState();
maybe_swift_ast_context->get()->GetPersistentExpressionState();
}

UserExpression *Target::GetUserExpressionForLanguage(
Expand Down Expand Up @@ -2423,7 +2424,7 @@ ClangASTImporterSP Target::GetClangASTImporter() {
return ClangASTImporterSP();
}

SwiftASTContextReader Target::GetScratchSwiftASTContext(
llvm::Optional<SwiftASTContextReader> Target::GetScratchSwiftASTContext(
Status &error, ExecutionContextScope &exe_scope, bool create_on_demand) {
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));

Expand Down Expand Up @@ -2504,7 +2505,9 @@ SwiftASTContextReader Target::GetScratchSwiftASTContext(
error);
}

return SwiftASTContextReader(GetSwiftScratchContextLock(), swift_ast_ctx);
if (!swift_ast_ctx)
return llvm::None;
return SwiftASTContextReader(GetSwiftScratchContextLock(), *swift_ast_ctx);
}

static SharedMutex *
Expand Down