| 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
|
|
|
|
|