diff --git a/patches/common/v8/.patches b/patches/common/v8/.patches index af2396167fd3..2de4290febde 100644 --- a/patches/common/v8/.patches +++ b/patches/common/v8/.patches @@ -4,3 +4,4 @@ build_gn.patch expose_mksnapshot.patch deps_provide_more_v8_backwards_compatibility.patch dcheck.patch +fixme_revert_heap_api_remove_deprecated_apis.patch diff --git a/patches/common/v8/add_realloc.patch b/patches/common/v8/add_realloc.patch index 45350d13fa7f..099aba80b543 100644 --- a/patches/common/v8/add_realloc.patch +++ b/patches/common/v8/add_realloc.patch @@ -12,10 +12,10 @@ when we override ReallocateBufferMemory, so we therefore need to implement Realloc on the v8 side. diff --git a/include/v8.h b/include/v8.h -index 6ecc48af33288c1d5b8a8d847581c1edd8c173f9..ea203a23a945a03e4494a1b3d615381dd5699e2c 100644 +index 6dee8ca634900af699ac1a54e10fc2a1ec4a7319..fd4e4f95022cb8e7332f9371ab478b8063cf048c 100644 --- a/include/v8.h +++ b/include/v8.h -@@ -4695,6 +4695,13 @@ class V8_EXPORT ArrayBuffer : public Object { +@@ -4694,6 +4694,13 @@ class V8_EXPORT ArrayBuffer : public Object { */ virtual void* AllocateUninitialized(size_t length) = 0; @@ -30,7 +30,7 @@ index 6ecc48af33288c1d5b8a8d847581c1edd8c173f9..ea203a23a945a03e4494a1b3d615381d * Free the memory block of size |length|, pointed to by |data|. * That memory is guaranteed to be previously allocated by |Allocate|. diff --git a/src/api.cc b/src/api.cc -index 168522f8c36b4385479ebba7f06f8a5261ab7a85..b87dfac21d26177128f7c434bc2577e18ab905c6 100644 +index a5bb14f935a0a96380cbaf9839a5063dbd420a16..b6071ee70e1f5f8c308118fc21fbab387129d07f 100644 --- a/src/api.cc +++ b/src/api.cc @@ -516,6 +516,10 @@ void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) { diff --git a/patches/common/v8/build_gn.patch b/patches/common/v8/build_gn.patch index a17338c5c11b..f111d9a719ad 100644 --- a/patches/common/v8/build_gn.patch +++ b/patches/common/v8/build_gn.patch @@ -5,10 +5,10 @@ Subject: build_gn.patch diff --git a/BUILD.gn b/BUILD.gn -index fddd525297773e843cbd7a8b11a72c3e094b06d8..d8a2b8e11a3e0e9820dca061a00dbf1a6859bcf4 100644 +index b843e32765a93fe50ccc78427558daeb3447c2a8..1eefb5b89c8a91ee3a9eb9f4a5b22cc499d97539 100644 --- a/BUILD.gn +++ b/BUILD.gn -@@ -240,7 +240,7 @@ config("internal_config") { +@@ -246,7 +246,7 @@ config("internal_config") { ":v8_header_features", ] @@ -17,7 +17,7 @@ index fddd525297773e843cbd7a8b11a72c3e094b06d8..d8a2b8e11a3e0e9820dca061a00dbf1a defines += [ "BUILDING_V8_SHARED" ] } } -@@ -3530,6 +3530,8 @@ if (v8_use_snapshot && current_toolchain == v8_snapshot_toolchain) { +@@ -3558,6 +3558,8 @@ if (v8_use_snapshot && current_toolchain == v8_snapshot_toolchain) { configs = [ ":internal_config" ] diff --git a/patches/common/v8/dcheck.patch b/patches/common/v8/dcheck.patch index e46538764c9b..c9f4983c8b5b 100644 --- a/patches/common/v8/dcheck.patch +++ b/patches/common/v8/dcheck.patch @@ -5,10 +5,10 @@ Subject: dcheck.patch diff --git a/src/api.cc b/src/api.cc -index 16b3d6d6d29ff6c79245e8f69132d7367708024e..3b5c0a8efa502cf0caf1dae9b426bab1c86d16b6 100644 +index a6c14a5be90679ed4d17fa04bb9feb30a05d42f9..8532ad08999316427add386696326b43dc1994d8 100644 --- a/src/api.cc +++ b/src/api.cc -@@ -8620,7 +8620,7 @@ void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) { +@@ -8617,7 +8617,7 @@ void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) { void Isolate::RunMicrotasks() { @@ -18,10 +18,10 @@ index 16b3d6d6d29ff6c79245e8f69132d7367708024e..3b5c0a8efa502cf0caf1dae9b426bab1 isolate->default_microtask_queue()->RunMicrotasks(isolate); } diff --git a/src/heap/heap.cc b/src/heap/heap.cc -index e72269d40a369f2e9ae9f12b54fe8f828e252a9a..1192c1ee6cc19eac3dff7ce36e364aa1403eafbc 100644 +index 18e357712e10060c70875a1c2e69b754a521efe1..eec4b79ead7c9cc980c7eaf100f103acc81b96f7 100644 --- a/src/heap/heap.cc +++ b/src/heap/heap.cc -@@ -4855,9 +4855,9 @@ void Heap::TearDown() { +@@ -4881,9 +4881,9 @@ void Heap::TearDown() { void Heap::AddGCPrologueCallback(v8::Isolate::GCCallbackWithData callback, GCType gc_type, void* data) { DCHECK_NOT_NULL(callback); diff --git a/patches/common/v8/deps_backport_detailed_line_info_for_cpu_profiler.patch b/patches/common/v8/deps_backport_detailed_line_info_for_cpu_profiler.patch index d34ac72c82aa..4d9adf7ba22e 100644 --- a/patches/common/v8/deps_backport_detailed_line_info_for_cpu_profiler.patch +++ b/patches/common/v8/deps_backport_detailed_line_info_for_cpu_profiler.patch @@ -20,10 +20,10 @@ Reviewed-By: James M Snell Reviewed-By: Ruben Bridgewater diff --git a/src/flag-definitions.h b/src/flag-definitions.h -index c7dc7520ebc17f63dbba74225000c84f6d3d0152..07d965d39ad08c9f0aa9af199ac4f0124c233bcd 100644 +index 75d8167ca3dc5728de8a0901996794da6acf6d19..c2c3db1dc683085d33a754c401bfec31b9ac08d7 100644 --- a/src/flag-definitions.h +++ b/src/flag-definitions.h -@@ -1321,7 +1321,7 @@ DEFINE_BOOL(log_function_events, false, +@@ -1337,7 +1337,7 @@ DEFINE_BOOL(log_function_events, false, DEFINE_BOOL(prof, false, "Log statistical profiling information (implies --log-code).") diff --git a/patches/common/v8/deps_provide_more_v8_backwards_compatibility.patch b/patches/common/v8/deps_provide_more_v8_backwards_compatibility.patch index e9d37b36ce74..37cce6512f8f 100644 --- a/patches/common/v8/deps_provide_more_v8_backwards_compatibility.patch +++ b/patches/common/v8/deps_provide_more_v8_backwards_compatibility.patch @@ -22,10 +22,10 @@ Reviewed-By: Yang Guo Reviewed-By: Michaƫl Zasso diff --git a/include/v8.h b/include/v8.h -index ea203a23a945a03e4494a1b3d615381dd5699e2c..6145cbca82fa30d42ef9e5ecf2caf7a571594098 100644 +index fd4e4f95022cb8e7332f9371ab478b8063cf048c..6a91f2571d1c0c7e92bff288da90a9550e5568ba 100644 --- a/include/v8.h +++ b/include/v8.h -@@ -1144,6 +1144,10 @@ class V8_EXPORT PrimitiveArray { +@@ -1141,6 +1141,10 @@ class V8_EXPORT PrimitiveArray { public: static Local New(Isolate* isolate, int length); int Length() const; @@ -36,7 +36,7 @@ index ea203a23a945a03e4494a1b3d615381dd5699e2c..6145cbca82fa30d42ef9e5ecf2caf7a5 void Set(Isolate* isolate, int index, Local item); Local Get(Isolate* isolate, int index); }; -@@ -1847,6 +1851,8 @@ class V8_EXPORT StackTrace { +@@ -1849,6 +1853,8 @@ class V8_EXPORT StackTrace { /** * Returns a StackFrame at a particular index. */ @@ -45,7 +45,7 @@ index ea203a23a945a03e4494a1b3d615381dd5699e2c..6145cbca82fa30d42ef9e5ecf2caf7a5 Local GetFrame(Isolate* isolate, uint32_t index) const; /** -@@ -2547,6 +2553,13 @@ class V8_EXPORT Value : public Data { +@@ -2549,6 +2555,13 @@ class V8_EXPORT Value : public Data { V8_DEPRECATE_SOON("Use maybe version", Local ToInt32(Isolate* isolate) const); @@ -59,7 +59,7 @@ index ea203a23a945a03e4494a1b3d615381dd5699e2c..6145cbca82fa30d42ef9e5ecf2caf7a5 /** * Attempts to convert a string to an array index. * Returns an empty handle if the conversion fails. -@@ -2566,7 +2579,14 @@ class V8_EXPORT Value : public Data { +@@ -2568,7 +2581,14 @@ class V8_EXPORT Value : public Data { Local context) const; V8_WARN_UNUSED_RESULT Maybe Int32Value(Local context) const; @@ -74,7 +74,7 @@ index ea203a23a945a03e4494a1b3d615381dd5699e2c..6145cbca82fa30d42ef9e5ecf2caf7a5 V8_WARN_UNUSED_RESULT Maybe Equals(Local context, Local that) const; bool StrictEquals(Local that) const; -@@ -2673,6 +2693,8 @@ class V8_EXPORT String : public Name { +@@ -2675,6 +2695,8 @@ class V8_EXPORT String : public Name { * Returns the number of bytes in the UTF-8 encoded * representation of this string. */ @@ -83,7 +83,7 @@ index ea203a23a945a03e4494a1b3d615381dd5699e2c..6145cbca82fa30d42ef9e5ecf2caf7a5 int Utf8Length(Isolate* isolate) const; /** -@@ -2729,12 +2751,23 @@ class V8_EXPORT String : public Name { +@@ -2731,12 +2753,23 @@ class V8_EXPORT String : public Name { // 16-bit character codes. int Write(Isolate* isolate, uint16_t* buffer, int start = 0, int length = -1, int options = NO_OPTIONS) const; @@ -107,7 +107,7 @@ index ea203a23a945a03e4494a1b3d615381dd5699e2c..6145cbca82fa30d42ef9e5ecf2caf7a5 /** * A zero length string. -@@ -2922,6 +2955,9 @@ class V8_EXPORT String : public Name { +@@ -2924,6 +2957,9 @@ class V8_EXPORT String : public Name { */ static Local Concat(Isolate* isolate, Local left, Local right); @@ -117,7 +117,7 @@ index ea203a23a945a03e4494a1b3d615381dd5699e2c..6145cbca82fa30d42ef9e5ecf2caf7a5 /** * Creates a new external string using the data defined in the given -@@ -2990,6 +3026,8 @@ class V8_EXPORT String : public Name { +@@ -2992,6 +3028,8 @@ class V8_EXPORT String : public Name { */ class V8_EXPORT Utf8Value { public: @@ -126,7 +126,7 @@ index ea203a23a945a03e4494a1b3d615381dd5699e2c..6145cbca82fa30d42ef9e5ecf2caf7a5 Utf8Value(Isolate* isolate, Local obj); ~Utf8Value(); char* operator*() { return str_; } -@@ -3013,6 +3051,7 @@ class V8_EXPORT String : public Name { +@@ -3015,6 +3053,7 @@ class V8_EXPORT String : public Name { */ class V8_EXPORT Value { public: @@ -134,7 +134,7 @@ index ea203a23a945a03e4494a1b3d615381dd5699e2c..6145cbca82fa30d42ef9e5ecf2caf7a5 Value(Isolate* isolate, Local obj); ~Value(); uint16_t* operator*() { return str_; } -@@ -5386,6 +5425,8 @@ class V8_EXPORT BooleanObject : public Object { +@@ -5385,6 +5424,8 @@ class V8_EXPORT BooleanObject : public Object { class V8_EXPORT StringObject : public Object { public: static Local New(Isolate* isolate, Local value); @@ -143,7 +143,7 @@ index ea203a23a945a03e4494a1b3d615381dd5699e2c..6145cbca82fa30d42ef9e5ecf2caf7a5 Local ValueOf() const; -@@ -10493,6 +10534,30 @@ template Value* Value::Cast(T* value) { +@@ -10476,6 +10517,30 @@ template Value* Value::Cast(T* value) { } @@ -175,10 +175,10 @@ index ea203a23a945a03e4494a1b3d615381dd5699e2c..6145cbca82fa30d42ef9e5ecf2caf7a5 #ifdef V8_ENABLE_CHECKS CheckCast(value); diff --git a/src/api.cc b/src/api.cc -index b87dfac21d26177128f7c434bc2577e18ab905c6..16b3d6d6d29ff6c79245e8f69132d7367708024e 100644 +index b6071ee70e1f5f8c308118fc21fbab387129d07f..a6c14a5be90679ed4d17fa04bb9feb30a05d42f9 100644 --- a/src/api.cc +++ b/src/api.cc -@@ -2227,6 +2227,10 @@ int PrimitiveArray::Length() const { +@@ -2220,6 +2220,10 @@ int PrimitiveArray::Length() const { return array->length(); } @@ -189,7 +189,7 @@ index b87dfac21d26177128f7c434bc2577e18ab905c6..16b3d6d6d29ff6c79245e8f69132d736 void PrimitiveArray::Set(Isolate* v8_isolate, int index, Local item) { i::Isolate* isolate = reinterpret_cast(v8_isolate); -@@ -2240,6 +2244,10 @@ void PrimitiveArray::Set(Isolate* v8_isolate, int index, +@@ -2233,6 +2237,10 @@ void PrimitiveArray::Set(Isolate* v8_isolate, int index, array->set(index, *i_item); } @@ -200,7 +200,7 @@ index b87dfac21d26177128f7c434bc2577e18ab905c6..16b3d6d6d29ff6c79245e8f69132d736 Local PrimitiveArray::Get(Isolate* v8_isolate, int index) { i::Isolate* isolate = reinterpret_cast(v8_isolate); i::Handle array = Utils::OpenHandle(this); -@@ -2945,6 +2953,10 @@ void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) { +@@ -2938,6 +2946,10 @@ void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) { // --- S t a c k T r a c e --- @@ -211,7 +211,7 @@ index b87dfac21d26177128f7c434bc2577e18ab905c6..16b3d6d6d29ff6c79245e8f69132d736 Local StackTrace::GetFrame(Isolate* v8_isolate, uint32_t index) const { i::Isolate* isolate = reinterpret_cast(v8_isolate); -@@ -3909,6 +3921,36 @@ void v8::RegExp::CheckCast(v8::Value* that) { +@@ -3902,6 +3914,36 @@ void v8::RegExp::CheckCast(v8::Value* that) { } @@ -248,7 +248,7 @@ index b87dfac21d26177128f7c434bc2577e18ab905c6..16b3d6d6d29ff6c79245e8f69132d736 Maybe Value::BooleanValue(Local context) const { i::Isolate* isolate = reinterpret_cast(context->GetIsolate()); return Just(Utils::OpenHandle(this)->BooleanValue(isolate)); -@@ -3997,6 +4039,12 @@ MaybeLocal Value::ToArrayIndex(Local context) const { +@@ -3990,6 +4032,12 @@ MaybeLocal Value::ToArrayIndex(Local context) const { } @@ -261,7 +261,7 @@ index b87dfac21d26177128f7c434bc2577e18ab905c6..16b3d6d6d29ff6c79245e8f69132d736 Maybe Value::Equals(Local context, Local that) const { i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate(); auto self = Utils::OpenHandle(this); -@@ -5275,6 +5323,10 @@ bool String::ContainsOnlyOneByte() const { +@@ -5268,6 +5316,10 @@ bool String::ContainsOnlyOneByte() const { return helper.Check(*str); } @@ -272,7 +272,7 @@ index b87dfac21d26177128f7c434bc2577e18ab905c6..16b3d6d6d29ff6c79245e8f69132d736 int String::Utf8Length(Isolate* isolate) const { i::Handle str = Utils::OpenHandle(this); str = i::String::Flatten(reinterpret_cast(isolate), str); -@@ -5427,6 +5479,14 @@ static int WriteUtf8Impl(i::Vector string, char* write_start, +@@ -5420,6 +5472,14 @@ static int WriteUtf8Impl(i::Vector string, char* write_start, } } // anonymous namespace @@ -287,7 +287,7 @@ index b87dfac21d26177128f7c434bc2577e18ab905c6..16b3d6d6d29ff6c79245e8f69132d736 int String::WriteUtf8(Isolate* v8_isolate, char* buffer, int capacity, int* nchars_ref, int options) const { i::Handle str = Utils::OpenHandle(this); -@@ -5467,6 +5527,18 @@ static inline int WriteHelper(i::Isolate* isolate, const String* string, +@@ -5460,6 +5520,18 @@ static inline int WriteHelper(i::Isolate* isolate, const String* string, } @@ -306,7 +306,7 @@ index b87dfac21d26177128f7c434bc2577e18ab905c6..16b3d6d6d29ff6c79245e8f69132d736 int String::WriteOneByte(Isolate* isolate, uint8_t* buffer, int start, int length, int options) const { return WriteHelper(reinterpret_cast(isolate), this, buffer, -@@ -6423,6 +6495,11 @@ MaybeLocal String::NewFromTwoByte(Isolate* isolate, +@@ -6414,6 +6486,11 @@ MaybeLocal String::NewFromTwoByte(Isolate* isolate, return result; } @@ -318,7 +318,7 @@ index b87dfac21d26177128f7c434bc2577e18ab905c6..16b3d6d6d29ff6c79245e8f69132d736 Local v8::String::Concat(Isolate* v8_isolate, Local left, Local right) { i::Isolate* isolate = reinterpret_cast(v8_isolate); -@@ -6705,6 +6782,11 @@ bool v8::BooleanObject::ValueOf() const { +@@ -6696,6 +6773,11 @@ bool v8::BooleanObject::ValueOf() const { } @@ -330,7 +330,7 @@ index b87dfac21d26177128f7c434bc2577e18ab905c6..16b3d6d6d29ff6c79245e8f69132d736 Local v8::StringObject::New(Isolate* v8_isolate, Local value) { i::Handle string = Utils::OpenHandle(*value); -@@ -8970,6 +9052,9 @@ bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8_isolate) { +@@ -8976,6 +9058,9 @@ bool MicrotasksScope::IsRunningMicrotasks(Isolate* v8_isolate) { return microtask_queue->IsRunningMicrotasks(); } @@ -340,7 +340,7 @@ index b87dfac21d26177128f7c434bc2577e18ab905c6..16b3d6d6d29ff6c79245e8f69132d736 String::Utf8Value::Utf8Value(v8::Isolate* isolate, v8::Local obj) : str_(nullptr), length_(0) { if (obj.IsEmpty()) return; -@@ -8989,6 +9074,9 @@ String::Utf8Value::~Utf8Value() { +@@ -8995,6 +9080,9 @@ String::Utf8Value::~Utf8Value() { i::DeleteArray(str_); } diff --git a/patches/common/v8/expose_mksnapshot.patch b/patches/common/v8/expose_mksnapshot.patch index 5a4b67754b1e..65eebb6fd097 100644 --- a/patches/common/v8/expose_mksnapshot.patch +++ b/patches/common/v8/expose_mksnapshot.patch @@ -6,10 +6,10 @@ Subject: expose_mksnapshot.patch Needed in order to target mksnapshot for mksnapshot zip. diff --git a/BUILD.gn b/BUILD.gn -index d8a2b8e11a3e0e9820dca061a00dbf1a6859bcf4..d3dbe37d0a145921dddaea72e394c87826d6d5fe 100644 +index 1eefb5b89c8a91ee3a9eb9f4a5b22cc499d97539..c2ec29b916155f36d8d181d82090afd857f4d041 100644 --- a/BUILD.gn +++ b/BUILD.gn -@@ -3520,8 +3520,6 @@ if (current_toolchain == v8_generator_toolchain) { +@@ -3548,8 +3548,6 @@ if (current_toolchain == v8_generator_toolchain) { if (v8_use_snapshot && current_toolchain == v8_snapshot_toolchain) { v8_executable("mksnapshot") { diff --git a/patches/common/v8/fixme_revert_heap_api_remove_deprecated_apis.patch b/patches/common/v8/fixme_revert_heap_api_remove_deprecated_apis.patch new file mode 100644 index 000000000000..d9f107d8178a --- /dev/null +++ b/patches/common/v8/fixme_revert_heap_api_remove_deprecated_apis.patch @@ -0,0 +1,261 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Samuel Attard +Date: Thu, 21 Mar 2019 22:29:55 -0700 +Subject: fixme: Revert "[heap,api] Remove deprecated APIs" + +This reverts commit f4b860d9b81956fb9d6815932522f4043fef56fa. + +This commit removes deprecated APIs that nan relies on, temporarily +reverting but we need to solve this with nan upstream + +diff --git a/include/v8-internal.h b/include/v8-internal.h +index cbdce1c3f60eed53f67968e6b89755f418aecc3f..9254f7c9a2f3cf7dc92421e2863109b410a09da0 100644 +--- a/include/v8-internal.h ++++ b/include/v8-internal.h +@@ -165,6 +165,7 @@ class Internals { + static const int kNodeStateMask = 0x7; + static const int kNodeStateIsWeakValue = 2; + static const int kNodeStateIsPendingValue = 3; ++ static const int kNodeStateIsNearDeathValue = 4; + static const int kNodeIsIndependentShift = 3; + static const int kNodeIsActiveShift = 4; + +diff --git a/include/v8.h b/include/v8.h +index 6a91f2571d1c0c7e92bff288da90a9550e5568ba..caafc04a404ba96a2669ddcaf4e5b1bb91984c1a 100644 +--- a/include/v8.h ++++ b/include/v8.h +@@ -577,6 +577,10 @@ template class PersistentBase { + + V8_DEPRECATED("See MarkIndependent.", V8_INLINE bool IsIndependent() const); + ++ /** Checks if the handle holds the only reference to an object. */ ++ V8_DEPRECATED("Garbage collection internal state should not be relied on.", ++ V8_INLINE bool IsNearDeath() const); ++ + /** Returns true if the handle's reference is weak. */ + V8_INLINE bool IsWeak() const; + +@@ -8565,6 +8569,17 @@ class V8_EXPORT Isolate { + */ + void VisitHandlesWithClassIds(PersistentHandleVisitor* visitor); + ++ /** ++ * Iterates through all the persistent handles in the current isolate's heap ++ * that have class_ids and are candidates to be marked as partially dependent ++ * handles. This will visit handles to young objects created since the last ++ * garbage collection but is free to visit an arbitrary superset of these ++ * objects. ++ */ ++ V8_DEPRECATED( ++ "Use VisitHandlesWithClassIds", ++ void VisitHandlesForPartialDependence(PersistentHandleVisitor* visitor)); ++ + /** + * Iterates through all the persistent handles in the current isolate's heap + * that have class_ids and are weak to be marked as inactive if there is no +@@ -9818,6 +9833,17 @@ bool PersistentBase::IsIndependent() const { + I::kNodeIsIndependentShift); + } + ++template ++bool PersistentBase::IsNearDeath() const { ++ typedef internal::Internals I; ++ if (this->IsEmpty()) return false; ++ uint8_t node_state = ++ I::GetNodeState(reinterpret_cast(this->val_)); ++ return node_state == I::kNodeStateIsNearDeathValue || ++ node_state == I::kNodeStateIsPendingValue; ++} ++ ++ + template + bool PersistentBase::IsWeak() const { + typedef internal::Internals I; +diff --git a/src/api.cc b/src/api.cc +index 8532ad08999316427add386696326b43dc1994d8..f2d26a3e7503fe09619259578606d2bc5bd16161 100644 +--- a/src/api.cc ++++ b/src/api.cc +@@ -8967,6 +8967,15 @@ void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) { + isolate->global_handles()->IterateAllRootsWithClassIds(visitor); + } + ++ ++void Isolate::VisitHandlesForPartialDependence( ++ PersistentHandleVisitor* visitor) { ++ i::Isolate* isolate = reinterpret_cast(this); ++ i::DisallowHeapAllocation no_allocation; ++ isolate->global_handles()->IterateAllYoungRootsWithClassIds(visitor); ++} ++ ++ + void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) { + i::Isolate* isolate = reinterpret_cast(this); + i::DisallowHeapAllocation no_allocation; +diff --git a/src/global-handles.cc b/src/global-handles.cc +index 350380b23ce6f4fe89e628285d2e69fb1cac88ee..5eb3d93f142ea4d6ec88a4468b6390ec5387da84 100644 +--- a/src/global-handles.cc ++++ b/src/global-handles.cc +@@ -379,6 +379,7 @@ class GlobalHandles::Node final : public NodeBase { + Internals::kNodeStateMask); + STATIC_ASSERT(WEAK == Internals::kNodeStateIsWeakValue); + STATIC_ASSERT(PENDING == Internals::kNodeStateIsPendingValue); ++ STATIC_ASSERT(NEAR_DEATH == Internals::kNodeStateIsNearDeathValue); + STATIC_ASSERT(static_cast(IsIndependent::kShift) == + Internals::kNodeIsIndependentShift); + STATIC_ASSERT(static_cast(IsActive::kShift) == +@@ -426,6 +427,11 @@ class GlobalHandles::Node final : public NodeBase { + flags_ = NodeWeaknessType::update(flags_, weakness_type); + } + ++ bool IsNearDeath() const { ++ // Check for PENDING to ensure correct answer when processing callbacks. ++ return state() == PENDING || state() == NEAR_DEATH; ++ } ++ + bool IsWeak() const { return state() == WEAK; } + + bool IsInUse() const { return state() != FREE; } +@@ -813,6 +819,10 @@ void GlobalHandles::AnnotateStrongRetainer(Address* location, + Node::FromLocation(location)->AnnotateStrongRetainer(label); + } + ++bool GlobalHandles::IsNearDeath(Address* location) { ++ return Node::FromLocation(location)->IsNearDeath(); ++} ++ + bool GlobalHandles::IsWeak(Address* location) { + return Node::FromLocation(location)->IsWeak(); + } +diff --git a/src/global-handles.h b/src/global-handles.h +index 8caa3c33ce72269ecd470328ad88260b2d6cb206..3604af1d28e5a899095335b033bca044a28b7d77 100644 +--- a/src/global-handles.h ++++ b/src/global-handles.h +@@ -73,6 +73,9 @@ class GlobalHandles final { + // Clear the weakness of a global handle. + static void* ClearWeakness(Address* location); + ++ // Tells whether global handle is near death. ++ static bool IsNearDeath(Address* location); ++ + // Tells whether global handle is weak. + static bool IsWeak(Address* location); + +diff --git a/test/cctest/heap/test-heap.cc b/test/cctest/heap/test-heap.cc +index fa3d5fe163fd1477c5bfba84d558172469e827f5..aae5f2d61f1b53389c8d4c3c511893010e49b59e 100644 +--- a/test/cctest/heap/test-heap.cc ++++ b/test/cctest/heap/test-heap.cc +@@ -531,9 +531,14 @@ TEST(WeakGlobalHandlesScavenge) { + + // Scavenge treats weak pointers as normal roots. + CcTest::CollectGarbage(NEW_SPACE); ++ + CHECK((*h1)->IsString()); + CHECK((*h2)->IsHeapNumber()); ++ + CHECK(!WeakPointerCleared); ++ CHECK(!global_handles->IsNearDeath(h2.location())); ++ CHECK(!global_handles->IsNearDeath(h1.location())); ++ + GlobalHandles::Destroy(h1.location()); + GlobalHandles::Destroy(h2.location()); + } +@@ -571,8 +576,11 @@ TEST(WeakGlobalUnmodifiedApiHandlesScavenge) { + &TestWeakGlobalHandleCallback, v8::WeakCallbackType::kParameter); + + CcTest::CollectGarbage(NEW_SPACE); ++ + CHECK((*h1)->IsHeapNumber()); + CHECK(WeakPointerCleared); ++ CHECK(!global_handles->IsNearDeath(h1.location())); ++ + GlobalHandles::Destroy(h1.location()); + } + +@@ -609,7 +617,10 @@ TEST(WeakGlobalApiHandleModifiedMapScavenge) { + &TestWeakGlobalHandleCallback, v8::WeakCallbackType::kParameter); + + CcTest::CollectGarbage(NEW_SPACE); ++ + CHECK(!WeakPointerCleared); ++ CHECK(!global_handles->IsNearDeath(h1.location())); ++ + GlobalHandles::Destroy(h1.location()); + } + +@@ -650,7 +661,10 @@ TEST(WeakGlobalApiHandleWithElementsScavenge) { + &TestWeakGlobalHandleCallback, v8::WeakCallbackType::kParameter); + + CcTest::CollectGarbage(NEW_SPACE); ++ + CHECK(!WeakPointerCleared); ++ CHECK(!global_handles->IsNearDeath(h1.location())); ++ + GlobalHandles::Destroy(h1.location()); + } + +@@ -685,11 +699,17 @@ TEST(WeakGlobalHandlesMark) { + GlobalHandles::MakeWeak( + h2.location(), reinterpret_cast(&handle_and_id), + &TestWeakGlobalHandleCallback, v8::WeakCallbackType::kParameter); ++ CHECK(!GlobalHandles::IsNearDeath(h1.location())); ++ CHECK(!GlobalHandles::IsNearDeath(h2.location())); + + // Incremental marking potentially marked handles before they turned weak. + CcTest::CollectAllGarbage(); ++ + CHECK((*h1)->IsString()); ++ + CHECK(WeakPointerCleared); ++ CHECK(!GlobalHandles::IsNearDeath(h1.location())); ++ + GlobalHandles::Destroy(h1.location()); + } + +diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc +index fc74e99dd45a57e8b8b88de6c666008074cdaeea..c2d796bb770432411e660c888a189685da474a41 100644 +--- a/test/cctest/test-api.cc ++++ b/test/cctest/test-api.cc +@@ -20472,6 +20472,43 @@ TEST(WrapperClassId) { + object.Reset(); + } + ++ ++TEST(PersistentHandleInNewSpaceVisitor) { ++ LocalContext context; ++ v8::Isolate* isolate = context->GetIsolate(); ++ v8::HandleScope scope(isolate); ++ v8::Persistent object1(isolate, v8::Object::New(isolate)); ++ CHECK_EQ(0, object1.WrapperClassId()); ++ object1.SetWrapperClassId(42); ++ CHECK_EQ(42, object1.WrapperClassId()); ++ ++ CcTest::CollectAllGarbage(); ++ CcTest::CollectAllGarbage(); ++ ++ v8::Persistent object2(isolate, v8::Object::New(isolate)); ++ CHECK_EQ(0, object2.WrapperClassId()); ++ object2.SetWrapperClassId(42); ++ CHECK_EQ(42, object2.WrapperClassId()); ++ ++ Visitor42 visitor(&object2); ++#if __clang__ ++#pragma clang diagnostic push ++#pragma clang diagnostic ignored "-Wdeprecated" ++#endif ++ // VisitHandlesForPartialDependence is marked deprecated. This test will be ++ // removed with the API method. ++ isolate->VisitHandlesForPartialDependence(&visitor); ++#if __clang__ ++#pragma clang diagnostic pop ++#endif ++ ++ CHECK_EQ(1, visitor.counter_); ++ ++ object1.Reset(); ++ object2.Reset(); ++} ++ ++ + TEST(RegExp) { + LocalContext context; + v8::HandleScope scope(context->GetIsolate());