Chromium Code Reviews| Index: src/factory.h |
| diff --git a/src/factory.h b/src/factory.h |
| index 0cb715772909cbf17b19a03b86c21c3ba3f81782..ce20177191aa69c97a3c8eac872cbe0cae2cc9a7 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 IdempotentHandleToPointerCodeTrampoline { |
|
Michael Starzinger
2013/07/05 07:49:07
nit: s/HandleToPointer/PointerToHandle/
danno
2013/07/05 09:35:54
Done.
|
| + public: |
| + explicit IdempotentHandleToPointerCodeTrampoline(Isolate* isolate) |
| + : isolate_(isolate) {} |
| + |
| + template<typename R> |
| + MUST_USE_RESULT MaybeObject* Call(R (*function)()) { |
| + int scavenges = isolate_->heap()->gc_count(); |
|
Michael Starzinger
2013/07/05 07:49:07
nit: Since this doesn't only count minor GCs, but
danno
2013/07/05 09:35:54
Done.
|
| + (*function)(); |
| + return (scavenges == isolate_->heap()->gc_count()) |
| + ? isolate_->heap()->true_value() |
| + : reinterpret_cast<MaybeObject*>(Failure::RetryAfterGC()); |
| + } |
| + |
| + template<typename R> |
| + MUST_USE_RESULT MaybeObject* CallWithReturnValue(R (*function)()) { |
| + int scavenges = isolate_->heap()->gc_count(); |
| + MaybeObject* result = (*function)(); |
|
Michael Starzinger
2013/07/05 07:49:07
I think the called function is not allowed to retu
danno
2013/07/05 09:35:54
Done.
|
| + return (scavenges == 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 scavenges = isolate_->heap()->gc_count(); |
| + (*function)(p1); |
| + return (scavenges == 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 scavenges = isolate_->heap()->gc_count(); |
| + MaybeObject* result = (*function)(p1); |
| + return (scavenges == 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 scavenges = isolate_->heap()->gc_count(); |
| + (*function)(p1, p2); |
| + return (scavenges == 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 scavenges = isolate_->heap()->gc_count(); |
| + MaybeObject* result = (*function)(p1, p2); |
| + return (scavenges == isolate_->heap()->gc_count()) |
| + ? result |
| + : reinterpret_cast<MaybeObject*>(Failure::RetryAfterGC()); |
| + } |
| + |
| + private: |
| + Isolate* isolate_; |
| +}; |
| + |
| } } // namespace v8::internal |