forked from rogchap/v8go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathisolate.go
117 lines (101 loc) · 3.19 KB
/
isolate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright 2019 Roger Chapman and the v8go contributors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package v8go
// #include "v8go.h"
import "C"
import (
"sync"
)
var v8once sync.Once
// Isolate is a JavaScript VM instance with its own heap and
// garbage collector. Most applications will create one isolate
// with many V8 contexts for execution.
type Isolate struct {
ptr C.IsolatePtr
cbMutex sync.RWMutex
cbSeq int
cbs map[int]FunctionCallback
}
// HeapStatistics represents V8 isolate heap statistics
type HeapStatistics struct {
TotalHeapSize uint64
TotalHeapSizeExecutable uint64
TotalPhysicalSize uint64
TotalAvailableSize uint64
UsedHeapSize uint64
HeapSizeLimit uint64
MallocedMemory uint64
ExternalMemory uint64
PeakMallocedMemory uint64
NumberOfNativeContexts uint64
NumberOfDetachedContexts uint64
}
// NewIsolate creates a new V8 isolate. Only one thread may access
// a given isolate at a time, but different threads may access
// different isolates simultaneously.
// When an isolate is no longer used its resources should be freed
// by calling iso.Dispose().
// An *Isolate can be used as a v8go.ContextOption to create a new
// Context, rather than creating a new default Isolate.
func NewIsolate() (*Isolate, error) {
v8once.Do(func() {
C.Init()
})
iso := &Isolate{
ptr: C.NewIsolate(),
cbs: make(map[int]FunctionCallback),
}
// TODO: [RC] catch any C++ exceptions and return as error
return iso, nil
}
// TerminateExecution terminates forcefully the current thread
// of JavaScript execution in the given isolate.
func (i *Isolate) TerminateExecution() {
C.IsolateTerminateExecution(i.ptr)
}
// GetHeapStatistics returns heap statistics for an isolate.
func (i *Isolate) GetHeapStatistics() HeapStatistics {
hs := C.IsolationGetHeapStatistics(i.ptr)
return HeapStatistics{
TotalHeapSize: uint64(hs.total_heap_size),
TotalHeapSizeExecutable: uint64(hs.total_heap_size_executable),
TotalPhysicalSize: uint64(hs.total_physical_size),
TotalAvailableSize: uint64(hs.total_available_size),
UsedHeapSize: uint64(hs.used_heap_size),
HeapSizeLimit: uint64(hs.heap_size_limit),
MallocedMemory: uint64(hs.malloced_memory),
ExternalMemory: uint64(hs.external_memory),
PeakMallocedMemory: uint64(hs.peak_malloced_memory),
NumberOfNativeContexts: uint64(hs.number_of_native_contexts),
NumberOfDetachedContexts: uint64(hs.number_of_detached_contexts),
}
}
// Dispose will dispose the Isolate VM; subsequent calls will panic.
func (i *Isolate) Dispose() {
if i.ptr == nil {
return
}
C.IsolateDispose(i.ptr)
i.ptr = nil
}
// Deprecated: use `iso.Dispose()`.
func (i *Isolate) Close() {
i.Dispose()
}
func (i *Isolate) apply(opts *contextOptions) {
opts.iso = i
}
func (i *Isolate) registerCallback(cb FunctionCallback) int {
i.cbMutex.Lock()
i.cbSeq++
ref := i.cbSeq
i.cbs[ref] = cb
i.cbMutex.Unlock()
return ref
}
func (i *Isolate) getCallback(ref int) FunctionCallback {
i.cbMutex.RLock()
defer i.cbMutex.RUnlock()
return i.cbs[ref]
}