1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/builtins/builtins-utils-inl.h"
6 #include "src/builtins/builtins.h"
7 #include "src/handles/maybe-handles-inl.h"
8 #include "src/heap/heap-inl.h" // For ToBoolean. TODO(jkummerow): Drop.
9 #include "src/logging/counters.h"
10 #include "src/numbers/conversions.h"
11 #include "src/objects/js-array-buffer-inl.h"
12 #include "src/objects/objects-inl.h"
13
14 namespace v8 {
15 namespace internal {
16
17 #define CHECK_SHARED(expected, name, method) \
18 if (name->is_shared() != expected) { \
19 THROW_NEW_ERROR_RETURN_FAILURE( \
20 isolate, \
21 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, \
22 isolate->factory()->NewStringFromAsciiChecked(method), \
23 name)); \
24 }
25
26 #define CHECK_RESIZABLE(expected, name, method) \
27 if (name->is_resizable() != expected) { \
28 THROW_NEW_ERROR_RETURN_FAILURE( \
29 isolate, \
30 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, \
31 isolate->factory()->NewStringFromAsciiChecked(method), \
32 name)); \
33 }
34
35 // -----------------------------------------------------------------------------
36 // ES#sec-arraybuffer-objects
37
38 namespace {
39
ConstructBuffer(Isolate * isolate,Handle<JSFunction> target,Handle<JSReceiver> new_target,Handle<Object> length,Handle<Object> max_length,InitializedFlag initialized)40 Object ConstructBuffer(Isolate* isolate, Handle<JSFunction> target,
41 Handle<JSReceiver> new_target, Handle<Object> length,
42 Handle<Object> max_length, InitializedFlag initialized) {
43 SharedFlag shared = *target != target->native_context().array_buffer_fun()
44 ? SharedFlag::kShared
45 : SharedFlag::kNotShared;
46 ResizableFlag resizable = max_length.is_null() ? ResizableFlag::kNotResizable
47 : ResizableFlag::kResizable;
48 Handle<JSObject> result;
49 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
50 isolate, result,
51 JSObject::New(target, new_target, Handle<AllocationSite>::null()));
52 auto array_buffer = Handle<JSArrayBuffer>::cast(result);
53 // Ensure that all fields are initialized because BackingStore::Allocate is
54 // allowed to GC. Note that we cannot move the allocation of the ArrayBuffer
55 // after BackingStore::Allocate because of the spec.
56 array_buffer->Setup(shared, resizable, nullptr);
57
58 size_t byte_length;
59 size_t max_byte_length = 0;
60 if (!TryNumberToSize(*length, &byte_length) ||
61 byte_length > JSArrayBuffer::kMaxByteLength) {
62 // ToNumber failed.
63 THROW_NEW_ERROR_RETURN_FAILURE(
64 isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength));
65 }
66
67 std::unique_ptr<BackingStore> backing_store;
68 if (resizable == ResizableFlag::kNotResizable) {
69 backing_store =
70 BackingStore::Allocate(isolate, byte_length, shared, initialized);
71 max_byte_length = byte_length;
72 } else {
73 if (!TryNumberToSize(*max_length, &max_byte_length)) {
74 THROW_NEW_ERROR_RETURN_FAILURE(
75 isolate,
76 NewRangeError(MessageTemplate::kInvalidArrayBufferMaxLength));
77 }
78 if (byte_length > max_byte_length) {
79 THROW_NEW_ERROR_RETURN_FAILURE(
80 isolate,
81 NewRangeError(MessageTemplate::kInvalidArrayBufferMaxLength));
82 }
83
84 size_t page_size, initial_pages, max_pages;
85 MAYBE_RETURN(JSArrayBuffer::GetResizableBackingStorePageConfiguration(
86 isolate, byte_length, max_byte_length, kThrowOnError,
87 &page_size, &initial_pages, &max_pages),
88 ReadOnlyRoots(isolate).exception());
89
90 constexpr bool kIsWasmMemory = false;
91 backing_store = BackingStore::TryAllocateAndPartiallyCommitMemory(
92 isolate, byte_length, max_byte_length, page_size, initial_pages,
93 max_pages, kIsWasmMemory, shared);
94 }
95 if (!backing_store) {
96 // Allocation of backing store failed.
97 THROW_NEW_ERROR_RETURN_FAILURE(
98 isolate, NewRangeError(MessageTemplate::kArrayBufferAllocationFailed));
99 }
100
101 array_buffer->Attach(std::move(backing_store));
102 array_buffer->set_max_byte_length(max_byte_length);
103 return *array_buffer;
104 }
105
106 } // namespace
107
108 // ES #sec-arraybuffer-constructor
BUILTIN(ArrayBufferConstructor)109 BUILTIN(ArrayBufferConstructor) {
110 HandleScope scope(isolate);
111 Handle<JSFunction> target = args.target();
112 DCHECK(*target == target->native_context().array_buffer_fun() ||
113 *target == target->native_context().shared_array_buffer_fun());
114 if (args.new_target()->IsUndefined(isolate)) { // [[Call]]
115 THROW_NEW_ERROR_RETURN_FAILURE(
116 isolate, NewTypeError(MessageTemplate::kConstructorNotFunction,
117 handle(target->shared().Name(), isolate)));
118 }
119 // [[Construct]]
120 Handle<JSReceiver> new_target = Handle<JSReceiver>::cast(args.new_target());
121 Handle<Object> length = args.atOrUndefined(isolate, 1);
122
123 Handle<Object> number_length;
124 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number_length,
125 Object::ToInteger(isolate, length));
126 if (number_length->Number() < 0.0) {
127 THROW_NEW_ERROR_RETURN_FAILURE(
128 isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferLength));
129 }
130
131 Handle<Object> number_max_length;
132 if (FLAG_harmony_rab_gsab) {
133 Handle<Object> max_length;
134 Handle<Object> options = args.atOrUndefined(isolate, 2);
135 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
136 isolate, max_length,
137 JSObject::ReadFromOptionsBag(
138 options, isolate->factory()->max_byte_length_string(), isolate));
139
140 if (!max_length->IsUndefined(isolate)) {
141 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
142 isolate, number_max_length, Object::ToInteger(isolate, max_length));
143 }
144 }
145 return ConstructBuffer(isolate, target, new_target, number_length,
146 number_max_length, InitializedFlag::kZeroInitialized);
147 }
148
149 // This is a helper to construct an ArrayBuffer with uinitialized memory.
150 // This means the caller must ensure the buffer is totally initialized in
151 // all cases, or we will expose uinitialized memory to user code.
BUILTIN(ArrayBufferConstructor_DoNotInitialize)152 BUILTIN(ArrayBufferConstructor_DoNotInitialize) {
153 HandleScope scope(isolate);
154 Handle<JSFunction> target(isolate->native_context()->array_buffer_fun(),
155 isolate);
156 Handle<Object> length = args.atOrUndefined(isolate, 1);
157 return ConstructBuffer(isolate, target, target, length, Handle<Object>(),
158 InitializedFlag::kUninitialized);
159 }
160
SliceHelper(BuiltinArguments args,Isolate * isolate,const char * kMethodName,bool is_shared)161 static Object SliceHelper(BuiltinArguments args, Isolate* isolate,
162 const char* kMethodName, bool is_shared) {
163 HandleScope scope(isolate);
164 Handle<Object> start = args.at(1);
165 Handle<Object> end = args.atOrUndefined(isolate, 2);
166
167 // * If Type(O) is not Object, throw a TypeError exception.
168 // * If O does not have an [[ArrayBufferData]] internal slot, throw a
169 // TypeError exception.
170 CHECK_RECEIVER(JSArrayBuffer, array_buffer, kMethodName);
171 // * [AB] If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
172 // * [SAB] If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
173 CHECK_SHARED(is_shared, array_buffer, kMethodName);
174
175 // * [AB] If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
176 if (!is_shared && array_buffer->was_detached()) {
177 THROW_NEW_ERROR_RETURN_FAILURE(
178 isolate, NewTypeError(MessageTemplate::kDetachedOperation,
179 isolate->factory()->NewStringFromAsciiChecked(
180 kMethodName)));
181 }
182
183 // * [AB] Let len be O.[[ArrayBufferByteLength]].
184 // * [SAB] Let len be O.[[ArrayBufferByteLength]].
185 double const len = array_buffer->GetByteLength();
186
187 // * Let relativeStart be ? ToInteger(start).
188 Handle<Object> relative_start;
189 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, relative_start,
190 Object::ToInteger(isolate, start));
191
192 // * If relativeStart < 0, let first be max((len + relativeStart), 0); else
193 // let first be min(relativeStart, len).
194 double const first = (relative_start->Number() < 0)
195 ? std::max(len + relative_start->Number(), 0.0)
196 : std::min(relative_start->Number(), len);
197
198 // * If end is undefined, let relativeEnd be len; else let relativeEnd be ?
199 // ToInteger(end).
200 double relative_end;
201 if (end->IsUndefined(isolate)) {
202 relative_end = len;
203 } else {
204 Handle<Object> relative_end_obj;
205 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, relative_end_obj,
206 Object::ToInteger(isolate, end));
207 relative_end = relative_end_obj->Number();
208 }
209
210 // * If relativeEnd < 0, let final be max((len + relativeEnd), 0); else let
211 // final be min(relativeEnd, len).
212 double const final_ = (relative_end < 0) ? std::max(len + relative_end, 0.0)
213 : std::min(relative_end, len);
214
215 // * Let newLen be max(final-first, 0).
216 double const new_len = std::max(final_ - first, 0.0);
217 Handle<Object> new_len_obj = isolate->factory()->NewNumber(new_len);
218
219 // * [AB] Let ctor be ? SpeciesConstructor(O, %ArrayBuffer%).
220 // * [SAB] Let ctor be ? SpeciesConstructor(O, %SharedArrayBuffer%).
221 Handle<JSFunction> constructor_fun = is_shared
222 ? isolate->shared_array_buffer_fun()
223 : isolate->array_buffer_fun();
224 Handle<Object> ctor;
225 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
226 isolate, ctor,
227 Object::SpeciesConstructor(
228 isolate, Handle<JSReceiver>::cast(args.receiver()), constructor_fun));
229
230 // * Let new be ? Construct(ctor, newLen).
231 Handle<JSReceiver> new_;
232 {
233 const int argc = 1;
234
235 base::ScopedVector<Handle<Object>> argv(argc);
236 argv[0] = new_len_obj;
237
238 Handle<Object> new_obj;
239 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
240 isolate, new_obj, Execution::New(isolate, ctor, argc, argv.begin()));
241
242 new_ = Handle<JSReceiver>::cast(new_obj);
243 }
244
245 // * If new does not have an [[ArrayBufferData]] internal slot, throw a
246 // TypeError exception.
247 if (!new_->IsJSArrayBuffer()) {
248 THROW_NEW_ERROR_RETURN_FAILURE(
249 isolate,
250 NewTypeError(MessageTemplate::kIncompatibleMethodReceiver,
251 isolate->factory()->NewStringFromAsciiChecked(kMethodName),
252 new_));
253 }
254
255 // * [AB] If IsSharedArrayBuffer(new) is true, throw a TypeError exception.
256 // * [SAB] If IsSharedArrayBuffer(new) is false, throw a TypeError exception.
257 Handle<JSArrayBuffer> new_array_buffer = Handle<JSArrayBuffer>::cast(new_);
258 CHECK_SHARED(is_shared, new_array_buffer, kMethodName);
259
260 // The created ArrayBuffer might or might not be resizable, since the species
261 // constructor might return a non-resizable or a resizable buffer.
262
263 // * [AB] If IsDetachedBuffer(new) is true, throw a TypeError exception.
264 if (!is_shared && new_array_buffer->was_detached()) {
265 THROW_NEW_ERROR_RETURN_FAILURE(
266 isolate, NewTypeError(MessageTemplate::kDetachedOperation,
267 isolate->factory()->NewStringFromAsciiChecked(
268 kMethodName)));
269 }
270
271 // * [AB] If SameValue(new, O) is true, throw a TypeError exception.
272 if (!is_shared && new_->SameValue(*args.receiver())) {
273 THROW_NEW_ERROR_RETURN_FAILURE(
274 isolate, NewTypeError(MessageTemplate::kArrayBufferSpeciesThis));
275 }
276
277 // * [SAB] If new.[[ArrayBufferData]] and O.[[ArrayBufferData]] are the same
278 // Shared Data Block values, throw a TypeError exception.
279 if (is_shared &&
280 new_array_buffer->backing_store() == array_buffer->backing_store()) {
281 THROW_NEW_ERROR_RETURN_FAILURE(
282 isolate, NewTypeError(MessageTemplate::kSharedArrayBufferSpeciesThis));
283 }
284
285 // * If new.[[ArrayBufferByteLength]] < newLen, throw a TypeError exception.
286 size_t new_array_buffer_byte_length = new_array_buffer->GetByteLength();
287 if (new_array_buffer_byte_length < new_len) {
288 THROW_NEW_ERROR_RETURN_FAILURE(
289 isolate,
290 NewTypeError(is_shared ? MessageTemplate::kSharedArrayBufferTooShort
291 : MessageTemplate::kArrayBufferTooShort));
292 }
293
294 // * [AB] NOTE: Side-effects of the above steps may have detached O.
295 // * [AB] If IsDetachedBuffer(O) is true, throw a TypeError exception.
296 if (!is_shared && array_buffer->was_detached()) {
297 THROW_NEW_ERROR_RETURN_FAILURE(
298 isolate, NewTypeError(MessageTemplate::kDetachedOperation,
299 isolate->factory()->NewStringFromAsciiChecked(
300 kMethodName)));
301 }
302
303 // * Let fromBuf be O.[[ArrayBufferData]].
304 // * Let toBuf be new.[[ArrayBufferData]].
305 // * Perform CopyDataBlockBytes(toBuf, 0, fromBuf, first, newLen).
306 size_t first_size = first;
307 size_t new_len_size = new_len;
308 DCHECK(new_array_buffer_byte_length >= new_len_size);
309
310 if (new_len_size != 0) {
311 size_t from_byte_length = array_buffer->GetByteLength();
312 if (V8_UNLIKELY(!is_shared && array_buffer->is_resizable())) {
313 // The above steps might have resized the underlying buffer. In that case,
314 // only copy the still-accessible portion of the underlying data.
315 if (first_size > from_byte_length) {
316 return *new_; // Nothing to copy.
317 }
318 if (new_len_size > from_byte_length - first_size) {
319 new_len_size = from_byte_length - first_size;
320 }
321 }
322 DCHECK(first_size <= from_byte_length);
323 DCHECK(from_byte_length - first_size >= new_len_size);
324 uint8_t* from_data =
325 reinterpret_cast<uint8_t*>(array_buffer->backing_store()) + first_size;
326 uint8_t* to_data =
327 reinterpret_cast<uint8_t*>(new_array_buffer->backing_store());
328 if (is_shared) {
329 base::Relaxed_Memcpy(reinterpret_cast<base::Atomic8*>(to_data),
330 reinterpret_cast<base::Atomic8*>(from_data),
331 new_len_size);
332 } else {
333 CopyBytes(to_data, from_data, new_len_size);
334 }
335 }
336
337 return *new_;
338 }
339
340 // ES #sec-sharedarraybuffer.prototype.slice
BUILTIN(SharedArrayBufferPrototypeSlice)341 BUILTIN(SharedArrayBufferPrototypeSlice) {
342 const char* const kMethodName = "SharedArrayBuffer.prototype.slice";
343 return SliceHelper(args, isolate, kMethodName, true);
344 }
345
346 // ES #sec-arraybuffer.prototype.slice
347 // ArrayBuffer.prototype.slice ( start, end )
BUILTIN(ArrayBufferPrototypeSlice)348 BUILTIN(ArrayBufferPrototypeSlice) {
349 const char* const kMethodName = "ArrayBuffer.prototype.slice";
350 return SliceHelper(args, isolate, kMethodName, false);
351 }
352
ResizeHelper(BuiltinArguments args,Isolate * isolate,const char * kMethodName,bool is_shared)353 static Object ResizeHelper(BuiltinArguments args, Isolate* isolate,
354 const char* kMethodName, bool is_shared) {
355 HandleScope scope(isolate);
356
357 // 1 Let O be the this value.
358 // 2. Perform ? RequireInternalSlot(O, [[ArrayBufferMaxByteLength]]).
359 CHECK_RECEIVER(JSArrayBuffer, array_buffer, kMethodName);
360 CHECK_RESIZABLE(true, array_buffer, kMethodName);
361
362 // [RAB] 3. If IsSharedArrayBuffer(O) is true, throw a *TypeError* exception
363 // [GSAB] 3. If IsSharedArrayBuffer(O) is false, throw a *TypeError* exception
364 CHECK_SHARED(is_shared, array_buffer, kMethodName);
365
366 // Let newByteLength to ? ToIntegerOrInfinity(newLength).
367 Handle<Object> new_length = args.at(1);
368 Handle<Object> number_new_byte_length;
369 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, number_new_byte_length,
370 Object::ToInteger(isolate, new_length));
371
372 // [RAB] If IsDetachedBuffer(O) is true, throw a TypeError exception.
373 if (!is_shared && array_buffer->was_detached()) {
374 THROW_NEW_ERROR_RETURN_FAILURE(
375 isolate, NewTypeError(MessageTemplate::kDetachedOperation,
376 isolate->factory()->NewStringFromAsciiChecked(
377 kMethodName)));
378 }
379
380 // [RAB] If newByteLength < 0 or newByteLength >
381 // O.[[ArrayBufferMaxByteLength]], throw a RangeError exception.
382
383 // [GSAB] If newByteLength < currentByteLength or newByteLength >
384 // O.[[ArrayBufferMaxByteLength]], throw a RangeError exception.
385 size_t new_byte_length;
386 if (!TryNumberToSize(*number_new_byte_length, &new_byte_length)) {
387 THROW_NEW_ERROR_RETURN_FAILURE(
388 isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferResizeLength,
389 isolate->factory()->NewStringFromAsciiChecked(
390 kMethodName)));
391 }
392
393 if (is_shared && new_byte_length < array_buffer->byte_length()) {
394 // GrowableSharedArrayBuffer is only allowed to grow.
395 THROW_NEW_ERROR_RETURN_FAILURE(
396 isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferResizeLength,
397 isolate->factory()->NewStringFromAsciiChecked(
398 kMethodName)));
399 }
400
401 if (new_byte_length > array_buffer->max_byte_length()) {
402 THROW_NEW_ERROR_RETURN_FAILURE(
403 isolate, NewRangeError(MessageTemplate::kInvalidArrayBufferResizeLength,
404 isolate->factory()->NewStringFromAsciiChecked(
405 kMethodName)));
406 }
407
408 size_t page_size = AllocatePageSize();
409 size_t new_committed_pages;
410 bool round_return_value =
411 RoundUpToPageSize(new_byte_length, page_size,
412 JSArrayBuffer::kMaxByteLength, &new_committed_pages);
413 CHECK(round_return_value);
414
415 // [RAB] Let hostHandled be ? HostResizeArrayBuffer(O, newByteLength).
416 // [GSAB] Let hostHandled be ? HostGrowArrayBuffer(O, newByteLength).
417 // If hostHandled is handled, return undefined.
418
419 // TODO(v8:11111, v8:12746): Wasm integration.
420
421 if (!is_shared) {
422 // [RAB] Let oldBlock be O.[[ArrayBufferData]].
423 // [RAB] Let newBlock be ? CreateByteDataBlock(newByteLength).
424 // [RAB] Let copyLength be min(newByteLength, O.[[ArrayBufferByteLength]]).
425 // [RAB] Perform CopyDataBlockBytes(newBlock, 0, oldBlock, 0, copyLength).
426 // [RAB] NOTE: Neither creation of the new Data Block nor copying from the
427 // old Data Block are observable. Implementations reserve the right to
428 // implement this method as in-place growth or shrinkage.
429 if (array_buffer->GetBackingStore()->ResizeInPlace(
430 isolate, new_byte_length, new_committed_pages * page_size) !=
431 BackingStore::ResizeOrGrowResult::kSuccess) {
432 THROW_NEW_ERROR_RETURN_FAILURE(
433 isolate, NewRangeError(MessageTemplate::kOutOfMemory,
434 isolate->factory()->NewStringFromAsciiChecked(
435 kMethodName)));
436 }
437 // [RAB] Set O.[[ArrayBufferByteLength]] to newLength.
438 array_buffer->set_byte_length(new_byte_length);
439 } else {
440 // [GSAB] (Detailed description of the algorithm omitted.)
441 auto result = array_buffer->GetBackingStore()->GrowInPlace(
442 isolate, new_byte_length, new_committed_pages * page_size);
443 if (result == BackingStore::ResizeOrGrowResult::kFailure) {
444 THROW_NEW_ERROR_RETURN_FAILURE(
445 isolate, NewRangeError(MessageTemplate::kOutOfMemory,
446 isolate->factory()->NewStringFromAsciiChecked(
447 kMethodName)));
448 }
449 if (result == BackingStore::ResizeOrGrowResult::kRace) {
450 THROW_NEW_ERROR_RETURN_FAILURE(
451 isolate,
452 NewRangeError(
453 MessageTemplate::kInvalidArrayBufferResizeLength,
454 isolate->factory()->NewStringFromAsciiChecked(kMethodName)));
455 }
456 // Invariant: byte_length for a GSAB is 0 (it needs to be read from the
457 // BackingStore).
458 CHECK_EQ(0, array_buffer->byte_length());
459 }
460 return ReadOnlyRoots(isolate).undefined_value();
461 }
462
463 // ES #sec-get-sharedarraybuffer.prototype.bytelength
464 // get SharedArrayBuffer.prototype.byteLength
BUILTIN(SharedArrayBufferPrototypeGetByteLength)465 BUILTIN(SharedArrayBufferPrototypeGetByteLength) {
466 const char* const kMethodName = "get SharedArrayBuffer.prototype.byteLength";
467 HandleScope scope(isolate);
468 // 1. Let O be the this value.
469 // 2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
470 CHECK_RECEIVER(JSArrayBuffer, array_buffer, kMethodName);
471 // 3. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
472 CHECK_SHARED(true, array_buffer, kMethodName);
473
474 DCHECK_EQ(array_buffer->max_byte_length(),
475 array_buffer->GetBackingStore()->max_byte_length());
476
477 // 4. Let length be ArrayBufferByteLength(O, SeqCst).
478 size_t byte_length = array_buffer->GetByteLength();
479 // 5. Return F(length).
480 return *isolate->factory()->NewNumberFromSize(byte_length);
481 }
482
483 // ES #sec-arraybuffer.prototype.resize
484 // ArrayBuffer.prototype.resize(new_size))
BUILTIN(ArrayBufferPrototypeResize)485 BUILTIN(ArrayBufferPrototypeResize) {
486 const char* const kMethodName = "ArrayBuffer.prototype.resize";
487 constexpr bool kIsShared = false;
488 return ResizeHelper(args, isolate, kMethodName, kIsShared);
489 }
490
491 // ES #sec-sharedarraybuffer.prototype.grow
492 // SharedArrayBuffer.prototype.grow(new_size))
BUILTIN(SharedArrayBufferPrototypeGrow)493 BUILTIN(SharedArrayBufferPrototypeGrow) {
494 const char* const kMethodName = "SharedArrayBuffer.prototype.grow";
495 constexpr bool kIsShared = true;
496 return ResizeHelper(args, isolate, kMethodName, kIsShared);
497 }
498
499 } // namespace internal
500 } // namespace v8
501