From d00a14392d978f0e0df54dbfb27b87e248613ab6 Mon Sep 17 00:00:00 2001 From: "danno@chromium.org" Date: Fri, 5 Jul 2013 09:36:11 +0000 Subject: [PATCH] Add trampoline to enable pointer -> handle code calls R=mstarzinger@chromium.org Review URL: https://codereview.chromium.org/18550002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15507 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/factory.h | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/heap.h | 2 ++ 2 files changed, 78 insertions(+) diff --git a/src/factory.h b/src/factory.h index 0cb7157..b39c4f4 100644 --- a/src/factory.h +++ b/src/factory.h @@ -564,6 +564,82 @@ Handle 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 + 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(Failure::RetryAfterGC()); + } + + template + 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(Failure::RetryAfterGC()); + } + + template + 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(Failure::RetryAfterGC()); + } + + template + 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(Failure::RetryAfterGC()); + } + + template + 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(Failure::RetryAfterGC()); + } + + template + 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(Failure::RetryAfterGC()); + } + + private: + Isolate* isolate_; +}; + } } // namespace v8::internal diff --git a/src/heap.h b/src/heap.h index d254b60..f020c7f 100644 --- a/src/heap.h +++ b/src/heap.h @@ -1812,6 +1812,8 @@ class Heap { void QueueMemoryChunkForFree(MemoryChunk* chunk); void FreeQueuedChunks(); + int gc_count() const { return gc_count_; } + // Completely clear the Instanceof cache (to stop it keeping objects alive // around a GC). inline void CompletelyClearInstanceofCache(); -- 2.7.4