Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(33)

Side by Side Diff: src/api-natives.cc

Issue 2170743003: [api] Introduce fast instantiations cache (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fixing uint issue under windows Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/bootstrapper.cc » ('j') | src/objects.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/api-natives.h" 5 #include "src/api-natives.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/isolate-inl.h" 8 #include "src/isolate-inl.h"
9 #include "src/lookup.h" 9 #include "src/lookup.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 15
16 namespace { 16 namespace {
17 17
18 class InvokeScope {
19 public:
20 explicit InvokeScope(Isolate* isolate)
21 : isolate_(isolate), save_context_(isolate) {}
22 ~InvokeScope() {
23 bool has_exception = isolate_->has_pending_exception();
24 if (has_exception) {
25 isolate_->ReportPendingMessages();
26 } else {
27 isolate_->clear_pending_message();
28 }
29 }
30
31 private:
32 Isolate* isolate_;
33 SaveContext save_context_;
34 };
35
18 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate, 36 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
19 Handle<ObjectTemplateInfo> data, 37 Handle<ObjectTemplateInfo> data,
20 Handle<JSReceiver> new_target, 38 Handle<JSReceiver> new_target,
21 bool is_hidden_prototype); 39 bool is_hidden_prototype);
22 40
23 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate, 41 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate,
24 Handle<FunctionTemplateInfo> data, 42 Handle<FunctionTemplateInfo> data,
25 Handle<Name> name = Handle<Name>()); 43 Handle<Name> name = Handle<Name>());
26 44
27 45
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 switch (intrinsic) { 164 switch (intrinsic) {
147 #define GET_INTRINSIC_VALUE(name, iname) \ 165 #define GET_INTRINSIC_VALUE(name, iname) \
148 case v8::k##name: \ 166 case v8::k##name: \
149 return native_context->iname(); 167 return native_context->iname();
150 V8_INTRINSICS_LIST(GET_INTRINSIC_VALUE) 168 V8_INTRINSICS_LIST(GET_INTRINSIC_VALUE)
151 #undef GET_INTRINSIC_VALUE 169 #undef GET_INTRINSIC_VALUE
152 } 170 }
153 return nullptr; 171 return nullptr;
154 } 172 }
155 173
156 // Returns parent function template or null.
157 FunctionTemplateInfo* GetParent(FunctionTemplateInfo* data) {
158 Object* parent = data->parent_template();
159 return parent->IsUndefined(data->GetIsolate())
160 ? nullptr
161 : FunctionTemplateInfo::cast(parent);
162 }
163
164 // Starting from given object template's constructor walk up the inheritance
165 // chain till a function template that has an instance template is found.
166 ObjectTemplateInfo* GetParent(ObjectTemplateInfo* data) {
167 Object* maybe_ctor = data->constructor();
168 Isolate* isolate = data->GetIsolate();
169 if (maybe_ctor->IsUndefined(isolate)) return nullptr;
170 FunctionTemplateInfo* ctor = FunctionTemplateInfo::cast(maybe_ctor);
171 while (true) {
172 ctor = GetParent(ctor);
173 if (ctor == nullptr) return nullptr;
174 Object* maybe_obj = ctor->instance_template();
175 if (!maybe_obj->IsUndefined(isolate)) {
176 return ObjectTemplateInfo::cast(maybe_obj);
177 }
178 }
179 }
180 174
181 template <typename TemplateInfoT> 175 template <typename TemplateInfoT>
182 MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj, 176 MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj,
183 Handle<TemplateInfoT> data, 177 Handle<TemplateInfoT> data,
184 bool is_hidden_prototype) { 178 bool is_hidden_prototype) {
185 HandleScope scope(isolate); 179 HandleScope scope(isolate);
186 // Disable access checks while instantiating the object. 180 // Disable access checks while instantiating the object.
187 AccessCheckDisableScope access_check_scope(isolate, obj); 181 AccessCheckDisableScope access_check_scope(isolate, obj);
188 182
189 // Walk the inheritance chain and copy all accessors to current object. 183 // Walk the inheritance chain and copy all accessors to current object.
190 int max_number_of_properties = 0; 184 int max_number_of_properties = 0;
191 TemplateInfoT* info = *data; 185 TemplateInfoT* info = *data;
192 while (info != nullptr) { 186 while (info != nullptr) {
193 if (!info->property_accessors()->IsUndefined(isolate)) { 187 if (!info->property_accessors()->IsUndefined(isolate)) {
194 Object* props = info->property_accessors(); 188 Object* props = info->property_accessors();
195 if (!props->IsUndefined(isolate)) { 189 if (!props->IsUndefined(isolate)) {
196 Handle<Object> props_handle(props, isolate); 190 Handle<Object> props_handle(props, isolate);
197 NeanderArray props_array(props_handle); 191 NeanderArray props_array(props_handle);
198 max_number_of_properties += props_array.length(); 192 max_number_of_properties += props_array.length();
199 } 193 }
200 } 194 }
201 info = GetParent(info); 195 info = info->GetParent(isolate);
202 } 196 }
203 197
204 if (max_number_of_properties > 0) { 198 if (max_number_of_properties > 0) {
205 int valid_descriptors = 0; 199 int valid_descriptors = 0;
206 // Use a temporary FixedArray to accumulate unique accessors. 200 // Use a temporary FixedArray to accumulate unique accessors.
207 Handle<FixedArray> array = 201 Handle<FixedArray> array =
208 isolate->factory()->NewFixedArray(max_number_of_properties); 202 isolate->factory()->NewFixedArray(max_number_of_properties);
209 203
210 info = *data; 204 info = *data;
211 while (info != nullptr) { 205 while (info != nullptr) {
212 // Accumulate accessors. 206 // Accumulate accessors.
213 if (!info->property_accessors()->IsUndefined(isolate)) { 207 if (!info->property_accessors()->IsUndefined(isolate)) {
214 Handle<Object> props(info->property_accessors(), isolate); 208 Handle<Object> props(info->property_accessors(), isolate);
215 valid_descriptors = 209 valid_descriptors =
216 AccessorInfo::AppendUnique(props, array, valid_descriptors); 210 AccessorInfo::AppendUnique(props, array, valid_descriptors);
217 } 211 }
218 info = GetParent(info); 212 info = info->GetParent(isolate);
219 } 213 }
220 214
221 // Install accumulated accessors. 215 // Install accumulated accessors.
222 for (int i = 0; i < valid_descriptors; i++) { 216 for (int i = 0; i < valid_descriptors; i++) {
223 Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i))); 217 Handle<AccessorInfo> accessor(AccessorInfo::cast(array->get(i)));
224 JSObject::SetAccessor(obj, accessor).Assert(); 218 JSObject::SetAccessor(obj, accessor).Assert();
225 } 219 }
226 } 220 }
227 221
228 auto property_list = handle(data->property_list(), isolate); 222 auto property_list = handle(data->property_list(), isolate);
229 if (property_list->IsUndefined(isolate)) return obj; 223 if (property_list->IsUndefined(isolate)) return obj;
230 // TODO(dcarney): just use a FixedArray here. 224 // TODO(dcarney): just use a FixedArray here.
231 NeanderArray properties(property_list); 225 NeanderArray properties(property_list);
232 if (properties.length() == 0) return obj; 226 if (properties.length() == 0) return obj;
233 227
234 int i = 0; 228 int i = 0;
235 for (int c = 0; c < data->number_of_properties(); c++) { 229 for (int c = 0; c < data->number_of_properties(); c++) {
236 auto name = handle(Name::cast(properties.get(i++)), isolate); 230 auto name = handle(Name::cast(properties.get(i++)), isolate);
237 auto bit = handle(properties.get(i++), isolate); 231 Object* bit = properties.get(i++);
238 if (bit->IsSmi()) { 232 if (bit->IsSmi()) {
239 PropertyDetails details(Smi::cast(*bit)); 233 PropertyDetails details(Smi::cast(bit));
240 PropertyAttributes attributes = details.attributes(); 234 PropertyAttributes attributes = details.attributes();
241 PropertyKind kind = details.kind(); 235 PropertyKind kind = details.kind();
242 236
243 if (kind == kData) { 237 if (kind == kData) {
244 auto prop_data = handle(properties.get(i++), isolate); 238 auto prop_data = handle(properties.get(i++), isolate);
245 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, 239 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name,
246 prop_data, attributes), 240 prop_data, attributes),
247 JSObject); 241 JSObject);
248 } else { 242 } else {
249 auto getter = handle(properties.get(i++), isolate); 243 auto getter = handle(properties.get(i++), isolate);
(...skipping 15 matching lines...) Expand all
265 auto prop_data = handle(GetIntrinsic(isolate, intrinsic), isolate); 259 auto prop_data = handle(GetIntrinsic(isolate, intrinsic), isolate);
266 260
267 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, 261 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name,
268 prop_data, attributes), 262 prop_data, attributes),
269 JSObject); 263 JSObject);
270 } 264 }
271 } 265 }
272 return obj; 266 return obj;
273 } 267 }
274 268
275 void CacheTemplateInstantiation(Isolate* isolate, uint32_t serial_number, 269 MaybeHandle<JSObject> ProbeInstantiationsCache(Isolate* isolate,
276 Handle<JSObject> object) { 270 int serial_number) {
277 auto cache = isolate->template_instantiations_cache(); 271 DCHECK_LE(1, serial_number);
278 auto new_cache = 272 if (serial_number <= TemplateInfo::kFastTemplateInstantiationsCacheSize) {
279 UnseededNumberDictionary::AtNumberPut(cache, serial_number, object); 273 Handle<FixedArray> fast_cache =
280 isolate->native_context()->set_template_instantiations_cache(*new_cache); 274 isolate->fast_template_instantiations_cache();
275 return fast_cache->GetValue<JSObject>(isolate, serial_number - 1);
276 } else {
277 Handle<UnseededNumberDictionary> slow_cache =
278 isolate->slow_template_instantiations_cache();
279 int entry = slow_cache->FindEntry(serial_number);
280 if (entry == UnseededNumberDictionary::kNotFound) {
281 return MaybeHandle<JSObject>();
282 }
283 return handle(JSObject::cast(slow_cache->ValueAt(entry)), isolate);
284 }
281 } 285 }
282 286
283 void UncacheTemplateInstantiation(Isolate* isolate, uint32_t serial_number) { 287 void CacheTemplateInstantiation(Isolate* isolate, int serial_number,
284 auto cache = isolate->template_instantiations_cache(); 288 Handle<JSObject> object) {
285 int entry = cache->FindEntry(serial_number); 289 DCHECK_LE(1, serial_number);
286 DCHECK(entry != UnseededNumberDictionary::kNotFound); 290 if (serial_number <= TemplateInfo::kFastTemplateInstantiationsCacheSize) {
287 Handle<Object> result = 291 Handle<FixedArray> fast_cache =
288 UnseededNumberDictionary::DeleteProperty(cache, entry); 292 isolate->fast_template_instantiations_cache();
289 USE(result); 293 Handle<FixedArray> new_cache =
290 DCHECK(result->IsTrue(isolate)); 294 FixedArray::SetAndGrow(fast_cache, serial_number - 1, object);
291 auto new_cache = UnseededNumberDictionary::Shrink(cache, entry); 295 if (*new_cache != *fast_cache) {
292 isolate->native_context()->set_template_instantiations_cache(*new_cache); 296 isolate->native_context()->set_fast_template_instantiations_cache(
297 *new_cache);
298 }
299 } else {
300 Handle<UnseededNumberDictionary> cache =
301 isolate->slow_template_instantiations_cache();
302 auto new_cache =
303 UnseededNumberDictionary::AtNumberPut(cache, serial_number, object);
304 if (*new_cache != *cache) {
305 isolate->native_context()->set_slow_template_instantiations_cache(
306 *new_cache);
307 }
308 }
309 }
310
311 void UncacheTemplateInstantiation(Isolate* isolate, int serial_number) {
312 DCHECK_LE(1, serial_number);
313 if (serial_number <= TemplateInfo::kFastTemplateInstantiationsCacheSize) {
314 Handle<FixedArray> fast_cache =
315 isolate->fast_template_instantiations_cache();
316 DCHECK(!fast_cache->get(serial_number - 1)->IsUndefined(isolate));
317 fast_cache->set_undefined(serial_number - 1);
318 } else {
319 Handle<UnseededNumberDictionary> cache =
320 isolate->slow_template_instantiations_cache();
321 int entry = cache->FindEntry(serial_number);
322 DCHECK(entry != UnseededNumberDictionary::kNotFound);
323 Handle<Object> result =
324 UnseededNumberDictionary::DeleteProperty(cache, entry);
325 USE(result);
326 DCHECK(result->IsTrue(isolate));
327 auto new_cache = UnseededNumberDictionary::Shrink(cache, entry);
328 isolate->native_context()->set_slow_template_instantiations_cache(
329 *new_cache);
330 }
331 }
332
333 bool IsSimpleInstantiation(Isolate* isolate, ObjectTemplateInfo* info,
334 JSReceiver* new_target) {
335 DisallowHeapAllocation no_gc;
336
337 if (!new_target->IsJSFunction()) return false;
338 JSFunction* fun = JSFunction::cast(new_target);
339 if (fun->shared()->function_data() != info->constructor()) return false;
340 if (info->immutable_proto()) return false;
341 return fun->context()->native_context() !=
342 isolate->context()->native_context();
293 } 343 }
294 344
295 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate, 345 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
296 Handle<ObjectTemplateInfo> info, 346 Handle<ObjectTemplateInfo> info,
297 Handle<JSReceiver> new_target, 347 Handle<JSReceiver> new_target,
298 bool is_hidden_prototype) { 348 bool is_hidden_prototype) {
299 Handle<JSFunction> constructor; 349 Handle<JSFunction> constructor;
300 uint32_t serial_number = 350 int serial_number = Smi::cast(info->serial_number())->value();
301 static_cast<uint32_t>(Smi::cast(info->serial_number())->value());
302 if (!new_target.is_null()) { 351 if (!new_target.is_null()) {
303 if (new_target->IsJSFunction() && 352 if (IsSimpleInstantiation(isolate, *info, *new_target)) {
304 JSFunction::cast(*new_target)->shared()->function_data() ==
305 info->constructor() &&
306 JSFunction::cast(*new_target)->context()->native_context() ==
307 isolate->context()->native_context() &&
308 !info->immutable_proto()) {
309 constructor = Handle<JSFunction>::cast(new_target); 353 constructor = Handle<JSFunction>::cast(new_target);
310 } else { 354 } else {
311 // Disable caching for subclass instantiation. 355 // Disable caching for subclass instantiation.
312 serial_number = 0; 356 serial_number = 0;
313 } 357 }
314 } 358 }
315 // Fast path. 359 // Fast path.
316 Handle<JSObject> result; 360 Handle<JSObject> result;
317 if (serial_number) { 361 if (serial_number) {
318 // Probe cache. 362 if (ProbeInstantiationsCache(isolate, serial_number).ToHandle(&result)) {
319 auto cache = isolate->template_instantiations_cache();
320 int entry = cache->FindEntry(serial_number);
321 if (entry != UnseededNumberDictionary::kNotFound) {
322 Object* boilerplate = cache->ValueAt(entry);
323 result = handle(JSObject::cast(boilerplate), isolate);
324 return isolate->factory()->CopyJSObject(result); 363 return isolate->factory()->CopyJSObject(result);
325 } 364 }
326 } 365 }
327 // Enter a new scope. Recursion could otherwise create a lot of handles.
328 HandleScope scope(isolate);
329 366
330 if (constructor.is_null()) { 367 if (constructor.is_null()) {
331 Handle<Object> cons(info->constructor(), isolate); 368 Object* maybe_constructor_info = info->constructor();
332 if (cons->IsUndefined(isolate)) { 369 if (maybe_constructor_info->IsUndefined(isolate)) {
333 constructor = isolate->object_function(); 370 constructor = isolate->object_function();
334 } else { 371 } else {
335 auto cons_templ = Handle<FunctionTemplateInfo>::cast(cons); 372 // Enter a new scope. Recursion could otherwise create a lot of handles.
336 ASSIGN_RETURN_ON_EXCEPTION(isolate, constructor, 373 HandleScope scope(isolate);
374 Handle<FunctionTemplateInfo> cons_templ(
375 FunctionTemplateInfo::cast(maybe_constructor_info), isolate);
376 Handle<JSFunction> tmp_constructor;
377 ASSIGN_RETURN_ON_EXCEPTION(isolate, tmp_constructor,
337 InstantiateFunction(isolate, cons_templ), 378 InstantiateFunction(isolate, cons_templ),
338 JSObject); 379 JSObject);
380 constructor = scope.CloseAndEscape(tmp_constructor);
339 } 381 }
340 382
341 if (new_target.is_null()) new_target = constructor; 383 if (new_target.is_null()) new_target = constructor;
342 } 384 }
343 385
344 Handle<JSObject> object; 386 Handle<JSObject> object;
345 ASSIGN_RETURN_ON_EXCEPTION(isolate, object, 387 ASSIGN_RETURN_ON_EXCEPTION(isolate, object,
346 JSObject::New(constructor, new_target), JSObject); 388 JSObject::New(constructor, new_target), JSObject);
347 ASSIGN_RETURN_ON_EXCEPTION( 389 ASSIGN_RETURN_ON_EXCEPTION(
348 isolate, result, 390 isolate, result,
349 ConfigureInstance(isolate, object, info, is_hidden_prototype), JSObject); 391 ConfigureInstance(isolate, object, info, is_hidden_prototype), JSObject);
350 if (info->immutable_proto()) { 392 if (info->immutable_proto()) {
351 JSObject::SetImmutableProto(object); 393 JSObject::SetImmutableProto(object);
352 } 394 }
353 // TODO(dcarney): is this necessary? 395 // TODO(dcarney): is this necessary?
354 JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject"); 396 JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject");
355 397
356 if (serial_number) { 398 if (serial_number) {
357 CacheTemplateInstantiation(isolate, serial_number, result); 399 CacheTemplateInstantiation(isolate, serial_number, result);
358 result = isolate->factory()->CopyJSObject(result); 400 result = isolate->factory()->CopyJSObject(result);
359 } 401 }
360 return scope.CloseAndEscape(result); 402 return result;
361 } 403 }
362 404
363 405
364 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate, 406 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate,
365 Handle<FunctionTemplateInfo> data, 407 Handle<FunctionTemplateInfo> data,
366 Handle<Name> name) { 408 Handle<Name> name) {
367 uint32_t serial_number = 409 int serial_number = Smi::cast(data->serial_number())->value();
368 static_cast<uint32_t>(Smi::cast(data->serial_number())->value());
369 if (serial_number) { 410 if (serial_number) {
370 // Probe cache. 411 Handle<JSObject> result;
371 auto cache = isolate->template_instantiations_cache(); 412 if (ProbeInstantiationsCache(isolate, serial_number).ToHandle(&result)) {
372 int entry = cache->FindEntry(serial_number); 413 return Handle<JSFunction>::cast(result);
373 if (entry != UnseededNumberDictionary::kNotFound) {
374 Object* element = cache->ValueAt(entry);
375 return handle(JSFunction::cast(element), isolate);
376 } 414 }
377 } 415 }
378 // Enter a new scope. Recursion could otherwise create a lot of handles.
379 HandleScope scope(isolate);
380 Handle<JSObject> prototype; 416 Handle<JSObject> prototype;
381 if (!data->remove_prototype()) { 417 if (!data->remove_prototype()) {
382 auto prototype_templ = handle(data->prototype_template(), isolate); 418 Object* prototype_templ = data->prototype_template();
383 if (prototype_templ->IsUndefined(isolate)) { 419 if (prototype_templ->IsUndefined(isolate)) {
384 prototype = isolate->factory()->NewJSObject(isolate->object_function()); 420 prototype = isolate->factory()->NewJSObject(isolate->object_function());
385 } else { 421 } else {
386 ASSIGN_RETURN_ON_EXCEPTION( 422 ASSIGN_RETURN_ON_EXCEPTION(
387 isolate, prototype, 423 isolate, prototype,
388 InstantiateObject(isolate, 424 InstantiateObject(
389 Handle<ObjectTemplateInfo>::cast(prototype_templ), 425 isolate,
390 Handle<JSReceiver>(), data->hidden_prototype()), 426 handle(ObjectTemplateInfo::cast(prototype_templ), isolate),
427 Handle<JSReceiver>(), data->hidden_prototype()),
391 JSFunction); 428 JSFunction);
392 } 429 }
393 auto parent = handle(data->parent_template(), isolate); 430 Object* parent = data->parent_template();
394 if (!parent->IsUndefined(isolate)) { 431 if (!parent->IsUndefined(isolate)) {
432 // Enter a new scope. Recursion could otherwise create a lot of handles.
433 HandleScope scope(isolate);
395 Handle<JSFunction> parent_instance; 434 Handle<JSFunction> parent_instance;
396 ASSIGN_RETURN_ON_EXCEPTION( 435 ASSIGN_RETURN_ON_EXCEPTION(
397 isolate, parent_instance, 436 isolate, parent_instance,
398 InstantiateFunction(isolate, 437 InstantiateFunction(
399 Handle<FunctionTemplateInfo>::cast(parent)), 438 isolate, handle(FunctionTemplateInfo::cast(parent), isolate)),
400 JSFunction); 439 JSFunction);
401 // TODO(dcarney): decide what to do here. 440 // TODO(dcarney): decide what to do here.
402 Handle<Object> parent_prototype; 441 Handle<Object> parent_prototype;
403 ASSIGN_RETURN_ON_EXCEPTION( 442 ASSIGN_RETURN_ON_EXCEPTION(
404 isolate, parent_prototype, 443 isolate, parent_prototype,
405 JSObject::GetProperty(parent_instance, 444 JSObject::GetProperty(parent_instance,
406 isolate->factory()->prototype_string()), 445 isolate->factory()->prototype_string()),
407 JSFunction); 446 JSFunction);
408 MAYBE_RETURN(JSObject::SetPrototype(prototype, parent_prototype, false, 447 MAYBE_RETURN(JSObject::SetPrototype(prototype, parent_prototype, false,
409 Object::THROW_ON_ERROR), 448 Object::THROW_ON_ERROR),
410 MaybeHandle<JSFunction>()); 449 MaybeHandle<JSFunction>());
411 } 450 }
412 } 451 }
413 auto function = ApiNatives::CreateApiFunction( 452 Handle<JSFunction> function = ApiNatives::CreateApiFunction(
414 isolate, data, prototype, ApiNatives::JavaScriptObjectType); 453 isolate, data, prototype, ApiNatives::JavaScriptObjectType);
415 if (!name.is_null() && name->IsString()) { 454 if (!name.is_null() && name->IsString()) {
416 function->shared()->set_name(*name); 455 function->shared()->set_name(*name);
417 } 456 }
418 if (serial_number) { 457 if (serial_number) {
419 // Cache the function. 458 // Cache the function.
420 CacheTemplateInstantiation(isolate, serial_number, function); 459 CacheTemplateInstantiation(isolate, serial_number, function);
421 } 460 }
422 auto result = 461 MaybeHandle<JSObject> result =
423 ConfigureInstance(isolate, function, data, data->hidden_prototype()); 462 ConfigureInstance(isolate, function, data, data->hidden_prototype());
424 if (result.is_null()) { 463 if (result.is_null()) {
425 // Uncache on error. 464 // Uncache on error.
426 if (serial_number) { 465 if (serial_number) {
427 UncacheTemplateInstantiation(isolate, serial_number); 466 UncacheTemplateInstantiation(isolate, serial_number);
428 } 467 }
429 return MaybeHandle<JSFunction>(); 468 return MaybeHandle<JSFunction>();
430 } 469 }
431 return scope.CloseAndEscape(function); 470 return function;
432 } 471 }
433 472
434 473
435 class InvokeScope {
436 public:
437 explicit InvokeScope(Isolate* isolate)
438 : isolate_(isolate), save_context_(isolate) {}
439 ~InvokeScope() {
440 bool has_exception = isolate_->has_pending_exception();
441 if (has_exception) {
442 isolate_->ReportPendingMessages();
443 } else {
444 isolate_->clear_pending_message();
445 }
446 }
447
448 private:
449 Isolate* isolate_;
450 SaveContext save_context_;
451 };
452
453
454 void AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ, 474 void AddPropertyToPropertyList(Isolate* isolate, Handle<TemplateInfo> templ,
455 int length, Handle<Object>* data) { 475 int length, Handle<Object>* data) {
456 auto list = handle(templ->property_list(), isolate); 476 auto list = handle(templ->property_list(), isolate);
457 if (list->IsUndefined(isolate)) { 477 if (list->IsUndefined(isolate)) {
458 list = NeanderArray(isolate).value(); 478 list = NeanderArray(isolate).value();
459 templ->set_property_list(*list); 479 templ->set_property_list(*list);
460 } 480 }
461 templ->set_number_of_properties(templ->number_of_properties() + 1); 481 templ->set_number_of_properties(templ->number_of_properties() + 1);
462 NeanderArray array(list); 482 NeanderArray array(list);
463 for (int i = 0; i < length; i++) { 483 for (int i = 0; i < length; i++) {
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 if (!obj->instance_call_handler()->IsUndefined(isolate)) { 683 if (!obj->instance_call_handler()->IsUndefined(isolate)) {
664 map->set_is_callable(); 684 map->set_is_callable();
665 map->set_is_constructor(true); 685 map->set_is_constructor(true);
666 } 686 }
667 687
668 return result; 688 return result;
669 } 689 }
670 690
671 } // namespace internal 691 } // namespace internal
672 } // namespace v8 692 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/bootstrapper.cc » ('j') | src/objects.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698