[type-profile] Use shared_ptr instead of raw pointer
If TypeProfile goes out of scope, ScriptData and Entry still rely on TypeProfiles's type_profile_. Make type_profile_ a shared_ptr owned by all three classes to prevent use after free. Bug: v8:5933 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Change-Id: Ida7d66dadc17a816cf4439a25e6f714edccffa2c Reviewed-on: https://chromium-review.googlesource.com/659937 Reviewed-by: Yang Guo <yangguo@chromium.org> Commit-Queue: Franziska Hinkelmann <franzih@chromium.org> Cr-Commit-Position: refs/heads/master@{#48013}
This commit is contained in:
parent
7540e841fa
commit
b069315832
17
src/api.cc
17
src/api.cc
@ -10182,9 +10182,6 @@ debug::Coverage::FunctionData debug::Coverage::ScriptData::GetFunctionData(
|
|||||||
return FunctionData(&script_->functions.at(i), coverage_);
|
return FunctionData(&script_->functions.at(i), coverage_);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug::Coverage::Coverage(std::shared_ptr<i::Coverage> coverage)
|
|
||||||
: coverage_(std::move(coverage)) {}
|
|
||||||
|
|
||||||
debug::Coverage::ScriptData::ScriptData(size_t index,
|
debug::Coverage::ScriptData::ScriptData(size_t index,
|
||||||
std::shared_ptr<i::Coverage> coverage)
|
std::shared_ptr<i::Coverage> coverage)
|
||||||
: script_(&coverage->at(index)), coverage_(std::move(coverage)) {}
|
: script_(&coverage->at(index)), coverage_(std::move(coverage)) {}
|
||||||
@ -10216,11 +10213,16 @@ int debug::TypeProfile::Entry::SourcePosition() const {
|
|||||||
std::vector<MaybeLocal<String>> debug::TypeProfile::Entry::Types() const {
|
std::vector<MaybeLocal<String>> debug::TypeProfile::Entry::Types() const {
|
||||||
std::vector<MaybeLocal<String>> result;
|
std::vector<MaybeLocal<String>> result;
|
||||||
for (const internal::Handle<internal::String>& type : entry_->types) {
|
for (const internal::Handle<internal::String>& type : entry_->types) {
|
||||||
result.push_back(ToApiHandle<String>(type));
|
result.emplace_back(ToApiHandle<String>(type));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug::TypeProfile::ScriptData::ScriptData(
|
||||||
|
size_t index, std::shared_ptr<i::TypeProfile> type_profile)
|
||||||
|
: script_(&type_profile->at(index)),
|
||||||
|
type_profile_(std::move(type_profile)) {}
|
||||||
|
|
||||||
Local<debug::Script> debug::TypeProfile::ScriptData::GetScript() const {
|
Local<debug::Script> debug::TypeProfile::ScriptData::GetScript() const {
|
||||||
return ToApiHandle<debug::Script>(script_->script);
|
return ToApiHandle<debug::Script>(script_->script);
|
||||||
}
|
}
|
||||||
@ -10229,7 +10231,7 @@ std::vector<debug::TypeProfile::Entry> debug::TypeProfile::ScriptData::Entries()
|
|||||||
const {
|
const {
|
||||||
std::vector<debug::TypeProfile::Entry> result;
|
std::vector<debug::TypeProfile::Entry> result;
|
||||||
for (const internal::TypeProfileEntry& entry : script_->entries) {
|
for (const internal::TypeProfileEntry& entry : script_->entries) {
|
||||||
result.push_back(debug::TypeProfile::Entry(&entry));
|
result.push_back(debug::TypeProfile::Entry(&entry, type_profile_));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -10248,12 +10250,9 @@ size_t debug::TypeProfile::ScriptCount() const { return type_profile_->size(); }
|
|||||||
|
|
||||||
debug::TypeProfile::ScriptData debug::TypeProfile::GetScriptData(
|
debug::TypeProfile::ScriptData debug::TypeProfile::GetScriptData(
|
||||||
size_t i) const {
|
size_t i) const {
|
||||||
// TODO(franzih): ScriptData is invalid after ~TypeProfile. Same in Coverage.
|
return ScriptData(i, type_profile_);
|
||||||
return ScriptData(&type_profile_->at(i));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debug::TypeProfile::~TypeProfile() { delete type_profile_; }
|
|
||||||
|
|
||||||
const char* CpuProfileNode::GetFunctionNameStr() const {
|
const char* CpuProfileNode::GetFunctionNameStr() const {
|
||||||
const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
|
const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
|
||||||
return node->entry()->name();
|
return node->entry()->name();
|
||||||
|
@ -341,7 +341,8 @@ class V8_EXPORT_PRIVATE Coverage {
|
|||||||
bool IsEmpty() const { return coverage_ == nullptr; }
|
bool IsEmpty() const { return coverage_ == nullptr; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Coverage(std::shared_ptr<i::Coverage> coverage);
|
explicit Coverage(std::shared_ptr<i::Coverage> coverage)
|
||||||
|
: coverage_(std::move(coverage)) {}
|
||||||
std::shared_ptr<i::Coverage> coverage_;
|
std::shared_ptr<i::Coverage> coverage_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -366,8 +367,12 @@ class V8_EXPORT_PRIVATE TypeProfile {
|
|||||||
std::vector<MaybeLocal<String>> Types() const;
|
std::vector<MaybeLocal<String>> Types() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit Entry(const i::TypeProfileEntry* entry) : entry_(entry) {}
|
explicit Entry(const i::TypeProfileEntry* entry,
|
||||||
|
std::shared_ptr<i::TypeProfile> type_profile)
|
||||||
|
: entry_(entry), type_profile_(std::move(type_profile)) {}
|
||||||
|
|
||||||
const i::TypeProfileEntry* entry_;
|
const i::TypeProfileEntry* entry_;
|
||||||
|
std::shared_ptr<i::TypeProfile> type_profile_;
|
||||||
|
|
||||||
friend class v8::debug::TypeProfile::ScriptData;
|
friend class v8::debug::TypeProfile::ScriptData;
|
||||||
};
|
};
|
||||||
@ -380,8 +385,11 @@ class V8_EXPORT_PRIVATE TypeProfile {
|
|||||||
std::vector<Entry> Entries() const;
|
std::vector<Entry> Entries() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit ScriptData(i::TypeProfileScript* script) : script_(script) {}
|
explicit ScriptData(size_t index,
|
||||||
|
std::shared_ptr<i::TypeProfile> type_profile);
|
||||||
|
|
||||||
i::TypeProfileScript* script_;
|
i::TypeProfileScript* script_;
|
||||||
|
std::shared_ptr<i::TypeProfile> type_profile_;
|
||||||
|
|
||||||
friend class v8::debug::TypeProfile;
|
friend class v8::debug::TypeProfile;
|
||||||
};
|
};
|
||||||
@ -393,12 +401,11 @@ class V8_EXPORT_PRIVATE TypeProfile {
|
|||||||
size_t ScriptCount() const;
|
size_t ScriptCount() const;
|
||||||
ScriptData GetScriptData(size_t i) const;
|
ScriptData GetScriptData(size_t i) const;
|
||||||
|
|
||||||
~TypeProfile();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit TypeProfile(i::TypeProfile* type_profile)
|
explicit TypeProfile(std::shared_ptr<i::TypeProfile> type_profile)
|
||||||
: type_profile_(type_profile) {}
|
: type_profile_(std::move(type_profile)) {}
|
||||||
i::TypeProfile* type_profile_;
|
|
||||||
|
std::shared_ptr<i::TypeProfile> type_profile_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ScopeIterator {
|
class ScopeIterator {
|
||||||
|
@ -12,8 +12,8 @@
|
|||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
TypeProfile* TypeProfile::Collect(Isolate* isolate) {
|
std::unique_ptr<TypeProfile> TypeProfile::Collect(Isolate* isolate) {
|
||||||
TypeProfile* result = new TypeProfile();
|
std::unique_ptr<TypeProfile> result(new TypeProfile());
|
||||||
|
|
||||||
// Collect existing feedback vectors.
|
// Collect existing feedback vectors.
|
||||||
std::vector<Handle<FeedbackVector>> feedback_vectors;
|
std::vector<Handle<FeedbackVector>> feedback_vectors;
|
||||||
|
@ -32,7 +32,7 @@ struct TypeProfileScript {
|
|||||||
|
|
||||||
class TypeProfile : public std::vector<TypeProfileScript> {
|
class TypeProfile : public std::vector<TypeProfileScript> {
|
||||||
public:
|
public:
|
||||||
static TypeProfile* Collect(Isolate* isolate);
|
static std::unique_ptr<TypeProfile> Collect(Isolate* isolate);
|
||||||
static void SelectMode(Isolate* isolate, debug::TypeProfile::Mode mode);
|
static void SelectMode(Isolate* isolate, debug::TypeProfile::Mode mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user