summaryrefslogtreecommitdiff
path: root/deps/v8/src/handles/global-handles.cc
diff options
context:
space:
mode:
authorMyles Borins <mylesborins@google.com>2019-09-24 11:56:38 -0400
committerMyles Borins <myles.borins@gmail.com>2019-10-07 03:19:23 -0400
commitf7f6c928c1c9c136b7926f892b8a2fda11d8b4b2 (patch)
treef5edbccb3ffda2573d70a6e291e7157f290e0ae0 /deps/v8/src/handles/global-handles.cc
parentffd22e81983056d09c064c59343a0e488236272d (diff)
downloadandroid-node-v8-f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2.tar.gz
android-node-v8-f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2.tar.bz2
android-node-v8-f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2.zip
deps: update V8 to 7.8.279.9
PR-URL: https://github.com/nodejs/node/pull/29694 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de> Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Diffstat (limited to 'deps/v8/src/handles/global-handles.cc')
-rw-r--r--deps/v8/src/handles/global-handles.cc100
1 files changed, 82 insertions, 18 deletions
diff --git a/deps/v8/src/handles/global-handles.cc b/deps/v8/src/handles/global-handles.cc
index db4f806e58..aed5b3fa83 100644
--- a/deps/v8/src/handles/global-handles.cc
+++ b/deps/v8/src/handles/global-handles.cc
@@ -22,6 +22,10 @@ namespace internal {
namespace {
+// Specifies whether V8 expects the holder memory of a global handle to be live
+// or dead.
+enum class HandleHolder { kLive, kDead };
+
constexpr size_t kBlockSize = 256;
} // namespace
@@ -32,6 +36,7 @@ class GlobalHandles::NodeBlock final {
using BlockType = NodeBlock<_NodeType>;
using NodeType = _NodeType;
+ V8_INLINE static const NodeBlock* From(const NodeType* node);
V8_INLINE static NodeBlock* From(NodeType* node);
NodeBlock(GlobalHandles* global_handles,
@@ -67,6 +72,16 @@ class GlobalHandles::NodeBlock final {
};
template <class NodeType>
+const GlobalHandles::NodeBlock<NodeType>*
+GlobalHandles::NodeBlock<NodeType>::From(const NodeType* node) {
+ uintptr_t ptr = reinterpret_cast<const uintptr_t>(node) -
+ sizeof(NodeType) * node->index();
+ const BlockType* block = reinterpret_cast<const BlockType*>(ptr);
+ DCHECK_EQ(node, block->at(node->index()));
+ return block;
+}
+
+template <class NodeType>
GlobalHandles::NodeBlock<NodeType>* GlobalHandles::NodeBlock<NodeType>::From(
NodeType* node) {
uintptr_t ptr =
@@ -239,6 +254,10 @@ void GlobalHandles::NodeSpace<NodeType>::Free(NodeType* node) {
template <class Child>
class NodeBase {
public:
+ static const Child* FromLocation(const Address* location) {
+ return reinterpret_cast<const Child*>(location);
+ }
+
static Child* FromLocation(Address* location) {
return reinterpret_cast<Child*>(location);
}
@@ -532,7 +551,8 @@ class GlobalHandles::Node final : public NodeBase<GlobalHandles::Node> {
set_state(NEAR_DEATH);
}
- void ResetPhantomHandle() {
+ void ResetPhantomHandle(HandleHolder handle_holder) {
+ DCHECK_EQ(HandleHolder::kLive, handle_holder);
DCHECK_EQ(PHANTOM_WEAK_RESET_HANDLE, weakness_type());
DCHECK_EQ(PENDING, state());
DCHECK_NULL(weak_callback_);
@@ -580,10 +600,9 @@ class GlobalHandles::Node final : public NodeBase<GlobalHandles::Node> {
// This stores three flags (independent, partially_dependent and
// in_young_list) and a State.
- class NodeState : public BitField8<State, 0, 3> {};
- class IsInYoungList : public BitField8<bool, NodeState::kNext, 1> {};
- class NodeWeaknessType
- : public BitField8<WeaknessType, IsInYoungList::kNext, 2> {};
+ using NodeState = BitField8<State, 0, 3>;
+ using IsInYoungList = NodeState::Next<bool, 1>;
+ using NodeWeaknessType = IsInYoungList::Next<WeaknessType, 2>;
// Handle specific callback - might be a weak reference in disguise.
WeakCallbackInfo<void>::Callback weak_callback_;
@@ -615,6 +634,9 @@ class GlobalHandles::TracedNode final
bool is_root() const { return IsRoot::decode(flags_); }
void set_root(bool v) { flags_ = IsRoot::update(flags_, v); }
+ bool has_destructor() const { return HasDestructor::decode(flags_); }
+ void set_has_destructor(bool v) { flags_ = HasDestructor::update(flags_, v); }
+
void SetFinalizationCallback(void* parameter,
WeakCallbackInfo<void>::Callback callback) {
set_parameter(parameter);
@@ -641,18 +663,21 @@ class GlobalHandles::TracedNode final
set_state(NEAR_DEATH);
}
- void ResetPhantomHandle() {
+ void ResetPhantomHandle(HandleHolder handle_holder) {
DCHECK(IsInUse());
- Address** handle = reinterpret_cast<Address**>(data_.parameter);
- *handle = nullptr;
+ if (handle_holder == HandleHolder::kLive) {
+ Address** handle = reinterpret_cast<Address**>(data_.parameter);
+ *handle = nullptr;
+ }
NodeSpace<TracedNode>::Release(this);
DCHECK(!IsInUse());
}
protected:
- class NodeState : public BitField8<State, 0, 2> {};
- class IsInYoungList : public BitField8<bool, NodeState::kNext, 1> {};
- class IsRoot : public BitField8<bool, IsInYoungList::kNext, 1> {};
+ using NodeState = BitField8<State, 0, 2>;
+ using IsInYoungList = NodeState::Next<bool, 1>;
+ using IsRoot = IsInYoungList::Next<bool, 1>;
+ using HasDestructor = IsRoot::Next<bool, 1>;
void ClearImplFields() {
set_root(true);
@@ -691,18 +716,21 @@ Handle<Object> GlobalHandles::Create(Address value) {
return Create(Object(value));
}
-Handle<Object> GlobalHandles::CreateTraced(Object value, Address* slot) {
+Handle<Object> GlobalHandles::CreateTraced(Object value, Address* slot,
+ bool has_destructor) {
GlobalHandles::TracedNode* result = traced_nodes_->Acquire(value);
if (ObjectInYoungGeneration(value) && !result->is_in_young_list()) {
traced_young_nodes_.push_back(result);
result->set_in_young_list(true);
}
result->set_parameter(slot);
+ result->set_has_destructor(has_destructor);
return result->handle();
}
-Handle<Object> GlobalHandles::CreateTraced(Address value, Address* slot) {
- return CreateTraced(Object(value), slot);
+Handle<Object> GlobalHandles::CreateTraced(Address value, Address* slot,
+ bool has_destructor) {
+ return CreateTraced(Object(value), slot, has_destructor);
}
Handle<Object> GlobalHandles::CopyGlobal(Address* location) {
@@ -717,6 +745,27 @@ Handle<Object> GlobalHandles::CopyGlobal(Address* location) {
return global_handles->Create(*location);
}
+// static
+void GlobalHandles::CopyTracedGlobal(const Address* const* from, Address** to) {
+ DCHECK_NOT_NULL(*from);
+ DCHECK_NULL(*to);
+ const TracedNode* node = TracedNode::FromLocation(*from);
+ // Copying a traced handle with finalization callback is prohibited because
+ // the callback may require knowing about multiple copies of the traced
+ // handle.
+ CHECK(!node->HasFinalizationCallback());
+ GlobalHandles* global_handles =
+ NodeBlock<TracedNode>::From(node)->global_handles();
+ Handle<Object> o = global_handles->CreateTraced(
+ node->object(), reinterpret_cast<Address*>(to), node->has_destructor());
+ *to = o.location();
+#ifdef VERIFY_HEAP
+ if (i::FLAG_verify_heap) {
+ Object(**to).ObjectVerify(global_handles->isolate());
+ }
+#endif // VERIFY_HEAP
+}
+
void GlobalHandles::MoveGlobal(Address** from, Address** to) {
DCHECK_NOT_NULL(*from);
DCHECK_NOT_NULL(*to);
@@ -809,7 +858,7 @@ void GlobalHandles::IterateWeakRootsForPhantomHandles(
should_reset_handle(isolate()->heap(), node->location())) {
if (node->IsPhantomResetHandle()) {
node->MarkPending();
- node->ResetPhantomHandle();
+ node->ResetPhantomHandle(HandleHolder::kLive);
++number_of_phantom_handle_resets_;
} else if (node->IsPhantomCallback()) {
node->MarkPending();
@@ -821,7 +870,8 @@ void GlobalHandles::IterateWeakRootsForPhantomHandles(
if (node->IsInUse() &&
should_reset_handle(isolate()->heap(), node->location())) {
if (node->IsPhantomResetHandle()) {
- node->ResetPhantomHandle();
+ node->ResetPhantomHandle(node->has_destructor() ? HandleHolder::kLive
+ : HandleHolder::kDead);
++number_of_phantom_handle_resets_;
} else {
node->CollectPhantomCallbackData(&traced_pending_phantom_callbacks_);
@@ -907,7 +957,7 @@ void GlobalHandles::IterateYoungWeakUnmodifiedRootsForPhantomHandles(
DCHECK(node->IsPhantomResetHandle() || node->IsPhantomCallback());
if (node->IsPhantomResetHandle()) {
node->MarkPending();
- node->ResetPhantomHandle();
+ node->ResetPhantomHandle(HandleHolder::kLive);
++number_of_phantom_handle_resets_;
} else if (node->IsPhantomCallback()) {
node->MarkPending();
@@ -922,6 +972,9 @@ void GlobalHandles::IterateYoungWeakUnmodifiedRootsForPhantomHandles(
}
}
}
+
+ LocalEmbedderHeapTracer* const tracer =
+ isolate()->heap()->local_embedder_heap_tracer();
for (TracedNode* node : traced_young_nodes_) {
if (!node->IsInUse()) continue;
@@ -929,7 +982,18 @@ void GlobalHandles::IterateYoungWeakUnmodifiedRootsForPhantomHandles(
!should_reset_handle(isolate_->heap(), node->location()));
if (should_reset_handle(isolate_->heap(), node->location())) {
if (node->IsPhantomResetHandle()) {
- node->ResetPhantomHandle();
+ if (node->has_destructor()) {
+ // For handles with destructor it is guaranteed that the embedder
+ // memory is still alive as the destructor would have otherwise
+ // removed the memory.
+ node->ResetPhantomHandle(HandleHolder::kLive);
+ } else {
+ v8::Value* value = ToApi<v8::Value>(node->handle());
+ tracer->ResetHandleInNonTracingGC(
+ *reinterpret_cast<v8::TracedGlobal<v8::Value>*>(&value));
+ DCHECK(!node->IsInUse());
+ }
+
++number_of_phantom_handle_resets_;
} else {
node->CollectPhantomCallbackData(&traced_pending_phantom_callbacks_);