Index: src/factory.h |
diff --git a/src/factory.h b/src/factory.h |
index 0cb715772909cbf17b19a03b86c21c3ba3f81782..b39c4f48af7fceb16aa0be1eb5cbf98e789b3d71 100644 |
--- a/src/factory.h |
+++ b/src/factory.h |
@@ -564,6 +564,82 @@ Handle<Object> Factory::NewNumberFromSize(size_t value, |
} |
+// Used to "safely" transition from pointer-based runtime code to Handle-based |
+// runtime code. When a GC happens during the called Handle-based code, a |
+// failure object is returned to the pointer-based code to cause it abort and |
+// re-trigger a gc of it's own. Since this double-gc will cause the Handle-based |
+// code to be called twice, it must be idempotent. |
+class IdempotentPointerToHandleCodeTrampoline { |
+ public: |
+ explicit IdempotentPointerToHandleCodeTrampoline(Isolate* isolate) |
+ : isolate_(isolate) {} |
+ |
+ template<typename R> |
+ MUST_USE_RESULT MaybeObject* Call(R (*function)()) { |
+ int collections = isolate_->heap()->gc_count(); |
+ (*function)(); |
+ return (collections == isolate_->heap()->gc_count()) |
+ ? isolate_->heap()->true_value() |
+ : reinterpret_cast<MaybeObject*>(Failure::RetryAfterGC()); |
+ } |
+ |
+ template<typename R> |
+ MUST_USE_RESULT MaybeObject* CallWithReturnValue(R (*function)()) { |
+ int collections = isolate_->heap()->gc_count(); |
+ Object* result = (*function)(); |
+ return (collections == isolate_->heap()->gc_count()) |
+ ? result |
+ : reinterpret_cast<MaybeObject*>(Failure::RetryAfterGC()); |
+ } |
+ |
+ template<typename R, typename P1> |
+ MUST_USE_RESULT MaybeObject* Call(R (*function)(P1), P1 p1) { |
+ int collections = isolate_->heap()->gc_count(); |
+ (*function)(p1); |
+ return (collections == isolate_->heap()->gc_count()) |
+ ? isolate_->heap()->true_value() |
+ : reinterpret_cast<MaybeObject*>(Failure::RetryAfterGC()); |
+ } |
+ |
+ template<typename R, typename P1> |
+ MUST_USE_RESULT MaybeObject* CallWithReturnValue( |
+ R (*function)(P1), |
+ P1 p1) { |
+ int collections = isolate_->heap()->gc_count(); |
+ Object* result = (*function)(p1); |
+ return (collections == isolate_->heap()->gc_count()) |
+ ? result |
+ : reinterpret_cast<MaybeObject*>(Failure::RetryAfterGC()); |
+ } |
+ |
+ template<typename R, typename P1, typename P2> |
+ MUST_USE_RESULT MaybeObject* Call( |
+ R (*function)(P1, P2), |
+ P1 p1, |
+ P2 p2) { |
+ int collections = isolate_->heap()->gc_count(); |
+ (*function)(p1, p2); |
+ return (collections == isolate_->heap()->gc_count()) |
+ ? isolate_->heap()->true_value() |
+ : reinterpret_cast<MaybeObject*>(Failure::RetryAfterGC()); |
+ } |
+ |
+ template<typename R, typename P1, typename P2> |
+ MUST_USE_RESULT MaybeObject* CallWithReturnValue( |
+ R (*function)(P1, P2), |
+ P1 p1, |
+ P2 p2) { |
+ int collections = isolate_->heap()->gc_count(); |
+ Object* result = (*function)(p1, p2); |
+ return (collections == isolate_->heap()->gc_count()) |
+ ? result |
+ : reinterpret_cast<MaybeObject*>(Failure::RetryAfterGC()); |
+ } |
+ |
+ private: |
+ Isolate* isolate_; |
+}; |
+ |
} } // namespace v8::internal |