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

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

Issue 2206773003: [api] Clean up scopes and precheck instantiations cache (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fixing omitted serial_number check 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/isolate.h » ('j') | no next file with comments »
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 { 18 class InvokeScope {
19 public: 19 public:
20 explicit InvokeScope(Isolate* isolate) 20 explicit InvokeScope(Isolate* isolate) : save_context_(isolate) {}
21 : isolate_(isolate), save_context_(isolate) {}
22 ~InvokeScope() { 21 ~InvokeScope() {
23 bool has_exception = isolate_->has_pending_exception(); 22 Isolate* isolate = save_context_.isolate();
23 bool has_exception = isolate->has_pending_exception();
24 if (has_exception) { 24 if (has_exception) {
25 isolate_->ReportPendingMessages(); 25 isolate->ReportPendingMessages();
26 } else { 26 } else {
27 isolate_->clear_pending_message(); 27 isolate->clear_pending_message();
28 } 28 }
29 } 29 }
30 30
31 private: 31 private:
32 Isolate* isolate_;
33 SaveContext save_context_; 32 SaveContext save_context_;
34 }; 33 };
35 34
36 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate, 35 enum class CacheCheck { kCheck, kSkip };
37 Handle<ObjectTemplateInfo> data,
38 Handle<JSReceiver> new_target,
39 bool is_hidden_prototype);
40 36
41 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate, 37 MaybeHandle<JSObject> InstantiateObject(
42 Handle<FunctionTemplateInfo> data, 38 Isolate* isolate, Handle<ObjectTemplateInfo> data,
43 Handle<Name> name = Handle<Name>()); 39 Handle<JSReceiver> new_target, CacheCheck cache_check = CacheCheck::kCheck,
40 bool is_hidden_prototype = false);
44 41
42 MaybeHandle<JSFunction> InstantiateFunction(
43 Isolate* isolate, Handle<FunctionTemplateInfo> data,
44 CacheCheck cache_check = CacheCheck::kCheck,
45 Handle<Name> name = Handle<Name>());
45 46
46 MaybeHandle<Object> Instantiate(Isolate* isolate, Handle<Object> data, 47 MaybeHandle<Object> Instantiate(Isolate* isolate, Handle<Object> data,
47 Handle<Name> name = Handle<Name>()) { 48 Handle<Name> name = Handle<Name>()) {
48 if (data->IsFunctionTemplateInfo()) { 49 if (data->IsFunctionTemplateInfo()) {
49 return InstantiateFunction(isolate, 50 return InstantiateFunction(isolate,
50 Handle<FunctionTemplateInfo>::cast(data), name); 51 Handle<FunctionTemplateInfo>::cast(data),
52 CacheCheck::kCheck, name);
51 } else if (data->IsObjectTemplateInfo()) { 53 } else if (data->IsObjectTemplateInfo()) {
52 return InstantiateObject(isolate, Handle<ObjectTemplateInfo>::cast(data), 54 return InstantiateObject(isolate, Handle<ObjectTemplateInfo>::cast(data),
53 Handle<JSReceiver>(), false); 55 Handle<JSReceiver>());
54 } else { 56 } else {
55 return data; 57 return data;
56 } 58 }
57 } 59 }
58 60
59 MaybeHandle<Object> DefineAccessorProperty( 61 MaybeHandle<Object> DefineAccessorProperty(
60 Isolate* isolate, Handle<JSObject> object, Handle<Name> name, 62 Isolate* isolate, Handle<JSObject> object, Handle<Name> name,
61 Handle<Object> getter, Handle<Object> setter, PropertyAttributes attributes, 63 Handle<Object> getter, Handle<Object> setter, PropertyAttributes attributes,
62 bool force_instantiate) { 64 bool force_instantiate) {
63 DCHECK(!getter->IsFunctionTemplateInfo() || 65 DCHECK(!getter->IsFunctionTemplateInfo() ||
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 DisallowHeapAllocation no_gc; 333 DisallowHeapAllocation no_gc;
332 334
333 if (!new_target->IsJSFunction()) return false; 335 if (!new_target->IsJSFunction()) return false;
334 JSFunction* fun = JSFunction::cast(new_target); 336 JSFunction* fun = JSFunction::cast(new_target);
335 if (fun->shared()->function_data() != info->constructor()) return false; 337 if (fun->shared()->function_data() != info->constructor()) return false;
336 if (info->immutable_proto()) return false; 338 if (info->immutable_proto()) return false;
337 return fun->context()->native_context() != 339 return fun->context()->native_context() !=
338 isolate->context()->native_context(); 340 isolate->context()->native_context();
339 } 341 }
340 342
343 MaybeHandle<JSObject> InstantiateObjectWithInvokeScope(
344 Isolate* isolate, Handle<ObjectTemplateInfo> info,
345 Handle<JSReceiver> new_target) {
346 InvokeScope invoke_scope(isolate);
347 return InstantiateObject(isolate, info, new_target, CacheCheck::kSkip);
348 }
349
341 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate, 350 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
342 Handle<ObjectTemplateInfo> info, 351 Handle<ObjectTemplateInfo> info,
343 Handle<JSReceiver> new_target, 352 Handle<JSReceiver> new_target,
353 CacheCheck cache_check,
344 bool is_hidden_prototype) { 354 bool is_hidden_prototype) {
345 Handle<JSFunction> constructor; 355 Handle<JSFunction> constructor;
346 int serial_number = Smi::cast(info->serial_number())->value(); 356 int serial_number = Smi::cast(info->serial_number())->value();
347 if (!new_target.is_null()) { 357 if (!new_target.is_null()) {
348 if (IsSimpleInstantiation(isolate, *info, *new_target)) { 358 if (IsSimpleInstantiation(isolate, *info, *new_target)) {
349 constructor = Handle<JSFunction>::cast(new_target); 359 constructor = Handle<JSFunction>::cast(new_target);
350 } else { 360 } else {
351 // Disable caching for subclass instantiation. 361 // Disable caching for subclass instantiation.
352 serial_number = 0; 362 serial_number = 0;
353 } 363 }
354 } 364 }
355 // Fast path. 365 // Fast path.
356 Handle<JSObject> result; 366 Handle<JSObject> result;
357 if (serial_number) { 367 if (serial_number && cache_check == CacheCheck::kCheck) {
358 if (ProbeInstantiationsCache(isolate, serial_number).ToHandle(&result)) { 368 if (ProbeInstantiationsCache(isolate, serial_number).ToHandle(&result)) {
359 return isolate->factory()->CopyJSObject(result); 369 return isolate->factory()->CopyJSObject(result);
360 } 370 }
361 } 371 }
362 372
363 if (constructor.is_null()) { 373 if (constructor.is_null()) {
364 Object* maybe_constructor_info = info->constructor(); 374 Object* maybe_constructor_info = info->constructor();
365 if (maybe_constructor_info->IsUndefined(isolate)) { 375 if (maybe_constructor_info->IsUndefined(isolate)) {
366 constructor = isolate->object_function(); 376 constructor = isolate->object_function();
367 } else { 377 } else {
(...skipping 13 matching lines...) Expand all
381 391
382 Handle<JSObject> object; 392 Handle<JSObject> object;
383 ASSIGN_RETURN_ON_EXCEPTION(isolate, object, 393 ASSIGN_RETURN_ON_EXCEPTION(isolate, object,
384 JSObject::New(constructor, new_target), JSObject); 394 JSObject::New(constructor, new_target), JSObject);
385 ASSIGN_RETURN_ON_EXCEPTION( 395 ASSIGN_RETURN_ON_EXCEPTION(
386 isolate, result, 396 isolate, result,
387 ConfigureInstance(isolate, object, info, is_hidden_prototype), JSObject); 397 ConfigureInstance(isolate, object, info, is_hidden_prototype), JSObject);
388 if (info->immutable_proto()) { 398 if (info->immutable_proto()) {
389 JSObject::SetImmutableProto(object); 399 JSObject::SetImmutableProto(object);
390 } 400 }
391 // TODO(dcarney): is this necessary?
392 JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject"); 401 JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject");
393 402
394 if (serial_number) { 403 if (serial_number) {
395 CacheTemplateInstantiation(isolate, serial_number, result); 404 CacheTemplateInstantiation(isolate, serial_number, result);
396 result = isolate->factory()->CopyJSObject(result); 405 result = isolate->factory()->CopyJSObject(result);
397 } 406 }
398 return result; 407 return result;
399 } 408 }
400 409
410 MaybeHandle<JSFunction> InstantiateFunctionWithInvokeScope(
411 Isolate* isolate, Handle<FunctionTemplateInfo> info) {
412 InvokeScope invoke_scope(isolate);
413 return InstantiateFunction(isolate, info, CacheCheck::kSkip);
414 }
401 415
402 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate, 416 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate,
403 Handle<FunctionTemplateInfo> data, 417 Handle<FunctionTemplateInfo> data,
418 CacheCheck cache_check,
404 Handle<Name> name) { 419 Handle<Name> name) {
405 int serial_number = Smi::cast(data->serial_number())->value(); 420 int serial_number = Smi::cast(data->serial_number())->value();
406 if (serial_number) { 421 if (serial_number && cache_check == CacheCheck::kCheck) {
407 Handle<JSObject> result; 422 Handle<JSObject> result;
408 if (ProbeInstantiationsCache(isolate, serial_number).ToHandle(&result)) { 423 if (ProbeInstantiationsCache(isolate, serial_number).ToHandle(&result)) {
409 return Handle<JSFunction>::cast(result); 424 return Handle<JSFunction>::cast(result);
410 } 425 }
411 } 426 }
412 Handle<JSObject> prototype; 427 Handle<JSObject> prototype;
413 if (!data->remove_prototype()) { 428 if (!data->remove_prototype()) {
414 Object* prototype_templ = data->prototype_template(); 429 Object* prototype_templ = data->prototype_template();
415 if (prototype_templ->IsUndefined(isolate)) { 430 if (prototype_templ->IsUndefined(isolate)) {
416 prototype = isolate->factory()->NewJSObject(isolate->object_function()); 431 prototype = isolate->factory()->NewJSObject(isolate->object_function());
417 } else { 432 } else {
418 ASSIGN_RETURN_ON_EXCEPTION( 433 ASSIGN_RETURN_ON_EXCEPTION(
419 isolate, prototype, 434 isolate, prototype,
420 InstantiateObject( 435 InstantiateObject(
421 isolate, 436 isolate,
422 handle(ObjectTemplateInfo::cast(prototype_templ), isolate), 437 handle(ObjectTemplateInfo::cast(prototype_templ), isolate),
423 Handle<JSReceiver>(), data->hidden_prototype()), 438 Handle<JSReceiver>(), CacheCheck::kCheck,
439 data->hidden_prototype()),
424 JSFunction); 440 JSFunction);
425 } 441 }
426 Object* parent = data->parent_template(); 442 Object* parent = data->parent_template();
427 if (!parent->IsUndefined(isolate)) { 443 if (!parent->IsUndefined(isolate)) {
428 // Enter a new scope. Recursion could otherwise create a lot of handles. 444 // Enter a new scope. Recursion could otherwise create a lot of handles.
429 HandleScope scope(isolate); 445 HandleScope scope(isolate);
430 Handle<JSFunction> parent_instance; 446 Handle<JSFunction> parent_instance;
431 ASSIGN_RETURN_ON_EXCEPTION( 447 ASSIGN_RETURN_ON_EXCEPTION(
432 isolate, parent_instance, 448 isolate, parent_instance,
433 InstantiateFunction( 449 InstantiateFunction(
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 data[i].is_null() 498 data[i].is_null()
483 ? Handle<Object>::cast(isolate->factory()->undefined_value()) 499 ? Handle<Object>::cast(isolate->factory()->undefined_value())
484 : data[i]; 500 : data[i];
485 list = TemplateList::Add(isolate, list, value); 501 list = TemplateList::Add(isolate, list, value);
486 } 502 }
487 templ->set_property_list(*list); 503 templ->set_property_list(*list);
488 } 504 }
489 505
490 } // namespace 506 } // namespace
491 507
492
493 MaybeHandle<JSFunction> ApiNatives::InstantiateFunction( 508 MaybeHandle<JSFunction> ApiNatives::InstantiateFunction(
494 Handle<FunctionTemplateInfo> data) { 509 Handle<FunctionTemplateInfo> info) {
495 Isolate* isolate = data->GetIsolate(); 510 Isolate* isolate = info->GetIsolate();
496 InvokeScope invoke_scope(isolate); 511 int serial_number = Smi::cast(info->serial_number())->value();
497 return ::v8::internal::InstantiateFunction(isolate, data); 512 if (serial_number) {
513 Handle<JSObject> result;
514 if (ProbeInstantiationsCache(isolate, serial_number).ToHandle(&result)) {
515 return Handle<JSFunction>::cast(result);
516 }
517 }
518 return InstantiateFunctionWithInvokeScope(isolate, info);
498 } 519 }
499 520
500 MaybeHandle<JSObject> ApiNatives::InstantiateObject( 521 MaybeHandle<JSObject> ApiNatives::InstantiateObject(
501 Handle<ObjectTemplateInfo> data, Handle<JSReceiver> new_target) { 522 Handle<ObjectTemplateInfo> info, Handle<JSReceiver> new_target) {
502 Isolate* isolate = data->GetIsolate(); 523 Isolate* isolate = info->GetIsolate();
503 InvokeScope invoke_scope(isolate); 524 int serial_number = Smi::cast(info->serial_number())->value();
504 return ::v8::internal::InstantiateObject(isolate, data, new_target, false); 525 if (serial_number && !new_target.is_null() &&
526 IsSimpleInstantiation(isolate, *info, *new_target)) {
527 // Fast path.
528 Handle<JSObject> result;
529 if (ProbeInstantiationsCache(isolate, serial_number).ToHandle(&result)) {
530 return isolate->factory()->CopyJSObject(result);
531 }
532 }
533 return InstantiateObjectWithInvokeScope(isolate, info, new_target);
505 } 534 }
506 535
507 MaybeHandle<JSObject> ApiNatives::InstantiateRemoteObject( 536 MaybeHandle<JSObject> ApiNatives::InstantiateRemoteObject(
508 Handle<ObjectTemplateInfo> data) { 537 Handle<ObjectTemplateInfo> data) {
509 Isolate* isolate = data->GetIsolate(); 538 Isolate* isolate = data->GetIsolate();
510 InvokeScope invoke_scope(isolate); 539 InvokeScope invoke_scope(isolate);
511 540
512 Handle<FunctionTemplateInfo> constructor( 541 Handle<FunctionTemplateInfo> constructor(
513 FunctionTemplateInfo::cast(data->constructor())); 542 FunctionTemplateInfo::cast(data->constructor()));
514 Handle<SharedFunctionInfo> shared = 543 Handle<SharedFunctionInfo> shared =
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 if (!obj->instance_call_handler()->IsUndefined(isolate)) { 712 if (!obj->instance_call_handler()->IsUndefined(isolate)) {
684 map->set_is_callable(); 713 map->set_is_callable();
685 map->set_is_constructor(true); 714 map->set_is_constructor(true);
686 } 715 }
687 716
688 return result; 717 return result;
689 } 718 }
690 719
691 } // namespace internal 720 } // namespace internal
692 } // namespace v8 721 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698