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

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

Issue 1609233002: Do not eagerly instantiate accessors' JSFunction. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Make GCMole happy again. Created 4 years, 10 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/arguments.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 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate, 18 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
19 Handle<ObjectTemplateInfo> data); 19 Handle<ObjectTemplateInfo> data,
20 20 bool is_hidden_prototype);
21 21
22 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate, 22 MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate,
23 Handle<FunctionTemplateInfo> data, 23 Handle<FunctionTemplateInfo> data,
24 Handle<Name> name = Handle<Name>()); 24 Handle<Name> name = Handle<Name>());
25 25
26 26
27 MaybeHandle<Object> Instantiate(Isolate* isolate, Handle<Object> data, 27 MaybeHandle<Object> Instantiate(Isolate* isolate, Handle<Object> data,
28 Handle<Name> name = Handle<Name>()) { 28 Handle<Name> name = Handle<Name>()) {
29 if (data->IsFunctionTemplateInfo()) { 29 if (data->IsFunctionTemplateInfo()) {
30 return InstantiateFunction(isolate, 30 return InstantiateFunction(isolate,
31 Handle<FunctionTemplateInfo>::cast(data), name); 31 Handle<FunctionTemplateInfo>::cast(data), name);
32 } else if (data->IsObjectTemplateInfo()) { 32 } else if (data->IsObjectTemplateInfo()) {
33 return InstantiateObject(isolate, Handle<ObjectTemplateInfo>::cast(data)); 33 return InstantiateObject(isolate, Handle<ObjectTemplateInfo>::cast(data),
34 false);
34 } else { 35 } else {
35 return data; 36 return data;
36 } 37 }
37 } 38 }
38 39
39 40 MaybeHandle<Object> DefineAccessorProperty(
40 MaybeHandle<Object> DefineAccessorProperty(Isolate* isolate, 41 Isolate* isolate, Handle<JSObject> object, Handle<Name> name,
41 Handle<JSObject> object, 42 Handle<Object> getter, Handle<Object> setter, PropertyAttributes attributes,
42 Handle<Name> name, 43 bool force_instantiate) {
43 Handle<Object> getter, 44 DCHECK(!getter->IsFunctionTemplateInfo() ||
44 Handle<Object> setter, 45 !FunctionTemplateInfo::cast(*getter)->do_not_cache());
45 PropertyAttributes attributes) { 46 DCHECK(!setter->IsFunctionTemplateInfo() ||
46 if (!getter->IsUndefined()) { 47 !FunctionTemplateInfo::cast(*setter)->do_not_cache());
47 ASSIGN_RETURN_ON_EXCEPTION( 48 if (force_instantiate) {
48 isolate, getter, 49 if (getter->IsFunctionTemplateInfo()) {
49 InstantiateFunction(isolate, 50 ASSIGN_RETURN_ON_EXCEPTION(
50 Handle<FunctionTemplateInfo>::cast(getter)), 51 isolate, getter,
51 Object); 52 InstantiateFunction(isolate,
52 } 53 Handle<FunctionTemplateInfo>::cast(getter)),
53 if (!setter->IsUndefined()) { 54 Object);
54 ASSIGN_RETURN_ON_EXCEPTION( 55 }
55 isolate, setter, 56 if (setter->IsFunctionTemplateInfo()) {
56 InstantiateFunction(isolate, 57 ASSIGN_RETURN_ON_EXCEPTION(
57 Handle<FunctionTemplateInfo>::cast(setter)), 58 isolate, setter,
58 Object); 59 InstantiateFunction(isolate,
60 Handle<FunctionTemplateInfo>::cast(setter)),
61 Object);
62 }
59 } 63 }
60 RETURN_ON_EXCEPTION(isolate, JSObject::DefineAccessor(object, name, getter, 64 RETURN_ON_EXCEPTION(isolate, JSObject::DefineAccessor(object, name, getter,
61 setter, attributes), 65 setter, attributes),
62 Object); 66 Object);
63 return object; 67 return object;
64 } 68 }
65 69
66 70
67 MaybeHandle<Object> DefineDataProperty(Isolate* isolate, 71 MaybeHandle<Object> DefineDataProperty(Isolate* isolate,
68 Handle<JSObject> object, 72 Handle<JSObject> object,
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 while (true) { 167 while (true) {
164 ctor = GetParent(ctor); 168 ctor = GetParent(ctor);
165 if (ctor == nullptr) return nullptr; 169 if (ctor == nullptr) return nullptr;
166 Object* maybe_obj = ctor->instance_template(); 170 Object* maybe_obj = ctor->instance_template();
167 if (!maybe_obj->IsUndefined()) return ObjectTemplateInfo::cast(maybe_obj); 171 if (!maybe_obj->IsUndefined()) return ObjectTemplateInfo::cast(maybe_obj);
168 } 172 }
169 } 173 }
170 174
171 template <typename TemplateInfoT> 175 template <typename TemplateInfoT>
172 MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj, 176 MaybeHandle<JSObject> ConfigureInstance(Isolate* isolate, Handle<JSObject> obj,
173 Handle<TemplateInfoT> data) { 177 Handle<TemplateInfoT> data,
178 bool is_hidden_prototype) {
174 HandleScope scope(isolate); 179 HandleScope scope(isolate);
175 // Disable access checks while instantiating the object. 180 // Disable access checks while instantiating the object.
176 AccessCheckDisableScope access_check_scope(isolate, obj); 181 AccessCheckDisableScope access_check_scope(isolate, obj);
177 182
178 // Walk the inheritance chain and copy all accessors to current object. 183 // Walk the inheritance chain and copy all accessors to current object.
179 int max_number_of_properties = 0; 184 int max_number_of_properties = 0;
180 TemplateInfoT* info = *data; 185 TemplateInfoT* info = *data;
181 while (info != nullptr) { 186 while (info != nullptr) {
182 if (!info->property_accessors()->IsUndefined()) { 187 if (!info->property_accessors()->IsUndefined()) {
183 Object* props = info->property_accessors(); 188 Object* props = info->property_accessors();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 PropertyKind kind = details.kind(); 235 PropertyKind kind = details.kind();
231 236
232 if (kind == kData) { 237 if (kind == kData) {
233 auto prop_data = handle(properties.get(i++), isolate); 238 auto prop_data = handle(properties.get(i++), isolate);
234 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name, 239 RETURN_ON_EXCEPTION(isolate, DefineDataProperty(isolate, obj, name,
235 prop_data, attributes), 240 prop_data, attributes),
236 JSObject); 241 JSObject);
237 } else { 242 } else {
238 auto getter = handle(properties.get(i++), isolate); 243 auto getter = handle(properties.get(i++), isolate);
239 auto setter = handle(properties.get(i++), isolate); 244 auto setter = handle(properties.get(i++), isolate);
240 RETURN_ON_EXCEPTION(isolate, 245 RETURN_ON_EXCEPTION(
241 DefineAccessorProperty(isolate, obj, name, getter, 246 isolate, DefineAccessorProperty(isolate, obj, name, getter, setter,
242 setter, attributes), 247 attributes, is_hidden_prototype),
243 JSObject); 248 JSObject);
244 } 249 }
245 } else { 250 } else {
246 // Intrinsic data property --- Get appropriate value from the current 251 // Intrinsic data property --- Get appropriate value from the current
247 // context. 252 // context.
248 PropertyDetails details(Smi::cast(properties.get(i++))); 253 PropertyDetails details(Smi::cast(properties.get(i++)));
249 PropertyAttributes attributes = details.attributes(); 254 PropertyAttributes attributes = details.attributes();
250 DCHECK_EQ(kData, details.kind()); 255 DCHECK_EQ(kData, details.kind());
251 256
252 v8::Intrinsic intrinsic = 257 v8::Intrinsic intrinsic =
253 static_cast<v8::Intrinsic>(Smi::cast(properties.get(i++))->value()); 258 static_cast<v8::Intrinsic>(Smi::cast(properties.get(i++))->value());
(...skipping 16 matching lines...) Expand all
270 275
271 void UncacheTemplateInstantiation(Isolate* isolate, Handle<Smi> serial_number) { 276 void UncacheTemplateInstantiation(Isolate* isolate, Handle<Smi> serial_number) {
272 auto cache = isolate->template_instantiations_cache(); 277 auto cache = isolate->template_instantiations_cache();
273 bool was_present = false; 278 bool was_present = false;
274 auto new_cache = ObjectHashTable::Remove(cache, serial_number, &was_present); 279 auto new_cache = ObjectHashTable::Remove(cache, serial_number, &was_present);
275 DCHECK(was_present); 280 DCHECK(was_present);
276 isolate->native_context()->set_template_instantiations_cache(*new_cache); 281 isolate->native_context()->set_template_instantiations_cache(*new_cache);
277 } 282 }
278 283
279 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate, 284 MaybeHandle<JSObject> InstantiateObject(Isolate* isolate,
280 Handle<ObjectTemplateInfo> info) { 285 Handle<ObjectTemplateInfo> info,
286 bool is_hidden_prototype) {
281 // Enter a new scope. Recursion could otherwise create a lot of handles. 287 // Enter a new scope. Recursion could otherwise create a lot of handles.
282 HandleScope scope(isolate); 288 HandleScope scope(isolate);
283 // Fast path. 289 // Fast path.
284 Handle<JSObject> result; 290 Handle<JSObject> result;
285 auto constructor = handle(info->constructor(), isolate); 291 auto constructor = handle(info->constructor(), isolate);
286 Handle<JSFunction> cons; 292 Handle<JSFunction> cons;
287 if (constructor->IsUndefined()) { 293 if (constructor->IsUndefined()) {
288 cons = isolate->object_function(); 294 cons = isolate->object_function();
289 } else { 295 } else {
290 auto cons_templ = Handle<FunctionTemplateInfo>::cast(constructor); 296 auto cons_templ = Handle<FunctionTemplateInfo>::cast(constructor);
291 ASSIGN_RETURN_ON_EXCEPTION( 297 ASSIGN_RETURN_ON_EXCEPTION(
292 isolate, cons, InstantiateFunction(isolate, cons_templ), JSFunction); 298 isolate, cons, InstantiateFunction(isolate, cons_templ), JSFunction);
293 } 299 }
294 auto serial_number = handle(Smi::cast(info->serial_number()), isolate); 300 auto serial_number = handle(Smi::cast(info->serial_number()), isolate);
295 if (serial_number->value()) { 301 if (serial_number->value()) {
296 // Probe cache. 302 // Probe cache.
297 auto cache = isolate->template_instantiations_cache(); 303 auto cache = isolate->template_instantiations_cache();
298 Object* boilerplate = cache->Lookup(serial_number); 304 Object* boilerplate = cache->Lookup(serial_number);
299 if (boilerplate->IsJSObject()) { 305 if (boilerplate->IsJSObject()) {
300 result = handle(JSObject::cast(boilerplate), isolate); 306 result = handle(JSObject::cast(boilerplate), isolate);
301 ASSIGN_RETURN_ON_EXCEPTION( 307 ASSIGN_RETURN_ON_EXCEPTION(
302 isolate, result, JSObject::DeepCopyApiBoilerplate(result), JSObject); 308 isolate, result, JSObject::DeepCopyApiBoilerplate(result), JSObject);
303 return scope.CloseAndEscape(result); 309 return scope.CloseAndEscape(result);
304 } 310 }
305 } 311 }
306 auto object = isolate->factory()->NewJSObject(cons); 312 auto object = isolate->factory()->NewJSObject(cons);
307 ASSIGN_RETURN_ON_EXCEPTION( 313 ASSIGN_RETURN_ON_EXCEPTION(
308 isolate, result, ConfigureInstance(isolate, object, info), JSFunction); 314 isolate, result,
315 ConfigureInstance(isolate, object, info, is_hidden_prototype),
316 JSFunction);
309 // TODO(dcarney): is this necessary? 317 // TODO(dcarney): is this necessary?
310 JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject"); 318 JSObject::MigrateSlowToFast(result, 0, "ApiNatives::InstantiateObject");
311 319
312 if (serial_number->value()) { 320 if (serial_number->value()) {
313 CacheTemplateInstantiation(isolate, serial_number, result); 321 CacheTemplateInstantiation(isolate, serial_number, result);
314 ASSIGN_RETURN_ON_EXCEPTION( 322 ASSIGN_RETURN_ON_EXCEPTION(
315 isolate, result, JSObject::DeepCopyApiBoilerplate(result), JSObject); 323 isolate, result, JSObject::DeepCopyApiBoilerplate(result), JSObject);
316 } 324 }
317 return scope.CloseAndEscape(result); 325 return scope.CloseAndEscape(result);
318 } 326 }
(...skipping 15 matching lines...) Expand all
334 HandleScope scope(isolate); 342 HandleScope scope(isolate);
335 Handle<JSObject> prototype; 343 Handle<JSObject> prototype;
336 if (!data->remove_prototype()) { 344 if (!data->remove_prototype()) {
337 auto prototype_templ = handle(data->prototype_template(), isolate); 345 auto prototype_templ = handle(data->prototype_template(), isolate);
338 if (prototype_templ->IsUndefined()) { 346 if (prototype_templ->IsUndefined()) {
339 prototype = isolate->factory()->NewJSObject(isolate->object_function()); 347 prototype = isolate->factory()->NewJSObject(isolate->object_function());
340 } else { 348 } else {
341 ASSIGN_RETURN_ON_EXCEPTION( 349 ASSIGN_RETURN_ON_EXCEPTION(
342 isolate, prototype, 350 isolate, prototype,
343 InstantiateObject(isolate, 351 InstantiateObject(isolate,
344 Handle<ObjectTemplateInfo>::cast(prototype_templ)), 352 Handle<ObjectTemplateInfo>::cast(prototype_templ),
353 data->hidden_prototype()),
345 JSFunction); 354 JSFunction);
346 } 355 }
347 auto parent = handle(data->parent_template(), isolate); 356 auto parent = handle(data->parent_template(), isolate);
348 if (!parent->IsUndefined()) { 357 if (!parent->IsUndefined()) {
349 Handle<JSFunction> parent_instance; 358 Handle<JSFunction> parent_instance;
350 ASSIGN_RETURN_ON_EXCEPTION( 359 ASSIGN_RETURN_ON_EXCEPTION(
351 isolate, parent_instance, 360 isolate, parent_instance,
352 InstantiateFunction(isolate, 361 InstantiateFunction(isolate,
353 Handle<FunctionTemplateInfo>::cast(parent)), 362 Handle<FunctionTemplateInfo>::cast(parent)),
354 JSFunction); 363 JSFunction);
(...skipping 11 matching lines...) Expand all
366 } 375 }
367 auto function = ApiNatives::CreateApiFunction( 376 auto function = ApiNatives::CreateApiFunction(
368 isolate, data, prototype, ApiNatives::JavaScriptObjectType); 377 isolate, data, prototype, ApiNatives::JavaScriptObjectType);
369 if (!name.is_null() && name->IsString()) { 378 if (!name.is_null() && name->IsString()) {
370 function->shared()->set_name(*name); 379 function->shared()->set_name(*name);
371 } 380 }
372 if (serial_number->value()) { 381 if (serial_number->value()) {
373 // Cache the function. 382 // Cache the function.
374 CacheTemplateInstantiation(isolate, serial_number, function); 383 CacheTemplateInstantiation(isolate, serial_number, function);
375 } 384 }
376 auto result = ConfigureInstance(isolate, function, data); 385 auto result =
386 ConfigureInstance(isolate, function, data, data->hidden_prototype());
377 if (result.is_null()) { 387 if (result.is_null()) {
378 // Uncache on error. 388 // Uncache on error.
379 if (serial_number->value()) { 389 if (serial_number->value()) {
380 UncacheTemplateInstantiation(isolate, serial_number); 390 UncacheTemplateInstantiation(isolate, serial_number);
381 } 391 }
382 return MaybeHandle<JSFunction>(); 392 return MaybeHandle<JSFunction>();
383 } 393 }
384 return scope.CloseAndEscape(function); 394 return scope.CloseAndEscape(function);
385 } 395 }
386 396
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 Isolate* isolate = data->GetIsolate(); 440 Isolate* isolate = data->GetIsolate();
431 InvokeScope invoke_scope(isolate); 441 InvokeScope invoke_scope(isolate);
432 return ::v8::internal::InstantiateFunction(isolate, data); 442 return ::v8::internal::InstantiateFunction(isolate, data);
433 } 443 }
434 444
435 445
436 MaybeHandle<JSObject> ApiNatives::InstantiateObject( 446 MaybeHandle<JSObject> ApiNatives::InstantiateObject(
437 Handle<ObjectTemplateInfo> data) { 447 Handle<ObjectTemplateInfo> data) {
438 Isolate* isolate = data->GetIsolate(); 448 Isolate* isolate = data->GetIsolate();
439 InvokeScope invoke_scope(isolate); 449 InvokeScope invoke_scope(isolate);
440 return ::v8::internal::InstantiateObject(isolate, data); 450 return ::v8::internal::InstantiateObject(isolate, data, false);
441 } 451 }
442 452
443 453
444 void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info, 454 void ApiNatives::AddDataProperty(Isolate* isolate, Handle<TemplateInfo> info,
445 Handle<Name> name, Handle<Object> value, 455 Handle<Name> name, Handle<Object> value,
446 PropertyAttributes attributes) { 456 PropertyAttributes attributes) {
447 const int kSize = 3; 457 const int kSize = 3;
448 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); 458 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
449 auto details_handle = handle(details.AsSmi(), isolate); 459 auto details_handle = handle(details.AsSmi(), isolate);
450 Handle<Object> data[kSize] = {name, details_handle, value}; 460 Handle<Object> data[kSize] = {name, details_handle, value};
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 map->set_is_callable(); 617 map->set_is_callable();
608 map->set_is_constructor(true); 618 map->set_is_constructor(true);
609 } 619 }
610 620
611 DCHECK(result->shared()->IsApiFunction()); 621 DCHECK(result->shared()->IsApiFunction());
612 return result; 622 return result;
613 } 623 }
614 624
615 } // namespace internal 625 } // namespace internal
616 } // namespace v8 626 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/arguments.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698