GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/sharedarraybuffer_metadata.cc Lines: 51 56 91.1 %
Date: 2019-09-24 22:36:24 Branches: 21 30 70.0 %

Line Branch Exec Source
1
#include "sharedarraybuffer_metadata.h"
2
3
#include "base_object-inl.h"
4
#include "memory_tracker-inl.h"
5
#include "node_errors.h"
6
#include "node_worker.h"
7
#include "util-inl.h"
8
9
#include <utility>
10
11
using v8::Context;
12
using v8::Function;
13
using v8::FunctionTemplate;
14
using v8::Local;
15
using v8::Maybe;
16
using v8::MaybeLocal;
17
using v8::Nothing;
18
using v8::Object;
19
using v8::SharedArrayBuffer;
20
using v8::Value;
21
22
namespace node {
23
namespace worker {
24
25
namespace {
26
27
// Yield a JS constructor for SABLifetimePartner objects in the form of a
28
// standard API object, that has a single field for containing the raw
29
// SABLifetimePartner* pointer.
30
624
Local<Function> GetSABLifetimePartnerConstructor(
31
    Environment* env, Local<Context> context) {
32
  Local<FunctionTemplate> templ;
33
624
  templ = env->sab_lifetimepartner_constructor_template();
34
625
  if (!templ.IsEmpty())
35
650
    return templ->GetFunction(context).ToLocalChecked();
36
37
300
  templ = BaseObject::MakeLazilyInitializedJSTemplate(env);
38
  templ->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(),
39
598
                                            "SABLifetimePartner"));
40
300
  env->set_sab_lifetimepartner_constructor_template(templ);
41
42
300
  return GetSABLifetimePartnerConstructor(env, context);
43
}
44
45
636
class SABLifetimePartner : public BaseObject {
46
 public:
47
324
  SABLifetimePartner(Environment* env,
48
                     Local<Object> obj,
49
                     SharedArrayBufferMetadataReference r)
50
    : BaseObject(env, obj),
51
324
      reference(std::move(r)) {
52
325
    MakeWeak();
53
324
  }
54
55
4
  SET_NO_MEMORY_INFO()
56
4
  SET_MEMORY_INFO_NAME(SABLifetimePartner)
57
4
  SET_SELF_SIZE(SABLifetimePartner)
58
59
  SharedArrayBufferMetadataReference reference;
60
};
61
62
}  // anonymous namespace
63
64
SharedArrayBufferMetadataReference
65
230
SharedArrayBufferMetadata::ForSharedArrayBuffer(
66
    Environment* env,
67
    Local<Context> context,
68
    Local<SharedArrayBuffer> source) {
69
  Local<Value> lifetime_partner;
70
71
690
  if (!source->GetPrivate(context,
72
230
                          env->sab_lifetimepartner_symbol())
73
690
                              .ToLocal(&lifetime_partner)) {
74
    return nullptr;
75
  }
76
77

1044
  if (lifetime_partner->IsObject() &&
78
      env->sab_lifetimepartner_constructor_template()
79
602
         ->HasInstance(lifetime_partner)) {
80
124
    CHECK(source->IsExternal());
81
    SABLifetimePartner* partner =
82
124
        Unwrap<SABLifetimePartner>(lifetime_partner.As<Object>());
83
124
    CHECK_NOT_NULL(partner);
84
124
    return partner->reference;
85
  }
86
87
106
  if (source->IsExternal()) {
88
    // If this is an external SharedArrayBuffer but we do not see a lifetime
89
    // partner object, it was not us who externalized it. In that case, there
90
    // is no way to serialize it, because it's unclear how the memory
91
    // is actually owned.
92
    THROW_ERR_TRANSFERRING_EXTERNALIZED_SHAREDARRAYBUFFER(env);
93
    return nullptr;
94
  }
95
96
  // If the SharedArrayBuffer is coming from a Worker, we need to make sure
97
  // that the corresponding ArrayBuffer::Allocator lives at least as long as
98
  // the SharedArrayBuffer itself.
99
106
  worker::Worker* w = env->worker_context();
100
  std::shared_ptr<v8::ArrayBuffer::Allocator> allocator =
101
106
      w != nullptr ? w->array_buffer_allocator() : nullptr;
102
103
106
  SharedArrayBuffer::Contents contents = source->Externalize();
104
  SharedArrayBufferMetadataReference r(
105
212
      new SharedArrayBufferMetadata(contents, allocator));
106
212
  if (r->AssignToSharedArrayBuffer(env, context, source).IsNothing())
107
    return nullptr;
108
212
  return r;
109
}
110
111
325
Maybe<bool> SharedArrayBufferMetadata::AssignToSharedArrayBuffer(
112
    Environment* env, Local<Context> context,
113
    Local<SharedArrayBuffer> target) {
114
325
  CHECK(target->IsExternal());
115
325
  Local<Function> ctor = GetSABLifetimePartnerConstructor(env, context);
116
  Local<Object> obj;
117
648
  if (!ctor->NewInstance(context).ToLocal(&obj))
118
    return Nothing<bool>();
119
120
324
  new SABLifetimePartner(env, obj, shared_from_this());
121
325
  return target->SetPrivate(context,
122
                            env->sab_lifetimepartner_symbol(),
123
650
                            obj);
124
}
125
126
106
SharedArrayBufferMetadata::SharedArrayBufferMetadata(
127
    const SharedArrayBuffer::Contents& contents,
128
    std::shared_ptr<v8::ArrayBuffer::Allocator> allocator)
129
106
  : contents_(contents), allocator_(allocator) { }
130
131
198
SharedArrayBufferMetadata::~SharedArrayBufferMetadata() {
132
99
  contents_.Deleter()(contents_.Data(),
133
                      contents_.ByteLength(),
134
99
                      contents_.DeleterData());
135
99
}
136
137
218
MaybeLocal<SharedArrayBuffer> SharedArrayBufferMetadata::GetSharedArrayBuffer(
138
    Environment* env, Local<Context> context) {
139
  Local<SharedArrayBuffer> obj =
140
      SharedArrayBuffer::New(env->isolate(),
141
                             contents_.Data(),
142
218
                             contents_.ByteLength());
143
144
438
  if (AssignToSharedArrayBuffer(env, context, obj).IsNothing())
145
1
    return MaybeLocal<SharedArrayBuffer>();
146
147
218
  return obj;
148
}
149
150
}  // namespace worker
151
}  // namespace node