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

Side by Side Diff: src/runtime.cc

Issue 14146005: Track representations of fields (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Only verify representation while transitioning Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 bool should_transform = 242 bool should_transform =
243 !is_result_from_cache && boilerplate->HasFastProperties(); 243 !is_result_from_cache && boilerplate->HasFastProperties();
244 if (should_transform || has_function_literal) { 244 if (should_transform || has_function_literal) {
245 // Normalize the properties of object to avoid n^2 behavior 245 // Normalize the properties of object to avoid n^2 behavior
246 // when extending the object multiple properties. Indicate the number of 246 // when extending the object multiple properties. Indicate the number of
247 // properties to be added. 247 // properties to be added.
248 JSObject::NormalizeProperties( 248 JSObject::NormalizeProperties(
249 boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2); 249 boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
250 } 250 }
251 251
252 // TODO(verwaest): This does not catch the case where the object stays in fast
253 // most from the beginning. However, since it may go slow by adding
254 // properties, currently only assume we'll ever be fast if we ensure
255 // converting it back to fast mode.
256 bool will_be_fast = should_transform && !has_function_literal;
252 for (int index = 0; index < length; index +=2) { 257 for (int index = 0; index < length; index +=2) {
253 Handle<Object> key(constant_properties->get(index+0), isolate); 258 Handle<Object> key(constant_properties->get(index+0), isolate);
254 Handle<Object> value(constant_properties->get(index+1), isolate); 259 Handle<Object> value(constant_properties->get(index+1), isolate);
255 if (value->IsFixedArray()) { 260 if (value->IsFixedArray()) {
256 // The value contains the constant_properties of a 261 // The value contains the constant_properties of a
257 // simple object or array literal. 262 // simple object or array literal.
258 Handle<FixedArray> array = Handle<FixedArray>::cast(value); 263 Handle<FixedArray> array = Handle<FixedArray>::cast(value);
259 value = CreateLiteralBoilerplate(isolate, literals, array); 264 value = CreateLiteralBoilerplate(isolate, literals, array);
260 if (value.is_null()) return value; 265 if (value.is_null()) return value;
266 } else if (value->IsUndefined()) {
267 // TODO(verwaest): Support storage types in the boilerplate.
268 // if (will_be_fast) {
269 // value = isolate->factory()->the_hole_value();
270 // } else {
271 // value = Handle<Object>(Smi::FromInt(0), isolate);
272 // }
261 } 273 }
262 Handle<Object> result; 274 Handle<Object> result;
263 uint32_t element_index = 0; 275 uint32_t element_index = 0;
264 if (key->IsInternalizedString()) { 276 if (key->IsInternalizedString()) {
265 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) { 277 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
266 // Array index as string (uint32). 278 // Array index as string (uint32).
267 result = JSObject::SetOwnElement( 279 result = JSObject::SetOwnElement(
268 boilerplate, element_index, value, kNonStrictMode); 280 boilerplate, element_index, value, kNonStrictMode);
269 } else { 281 } else {
270 Handle<String> name(String::cast(*key)); 282 Handle<String> name(String::cast(*key));
(...skipping 21 matching lines...) Expand all
292 // exception, the exception is converted to an empty handle in 304 // exception, the exception is converted to an empty handle in
293 // the handle based operations. In that case, we need to 305 // the handle based operations. In that case, we need to
294 // convert back to an exception. 306 // convert back to an exception.
295 if (result.is_null()) return result; 307 if (result.is_null()) return result;
296 } 308 }
297 309
298 // Transform to fast properties if necessary. For object literals with 310 // Transform to fast properties if necessary. For object literals with
299 // containing function literals we defer this operation until after all 311 // containing function literals we defer this operation until after all
300 // computed properties have been assigned so that we can generate 312 // computed properties have been assigned so that we can generate
301 // constant function properties. 313 // constant function properties.
302 if (should_transform && !has_function_literal) { 314 if (will_be_fast) {
303 JSObject::TransformToFastProperties( 315 JSObject::TransformToFastProperties(
304 boilerplate, boilerplate->map()->unused_property_fields()); 316 boilerplate, boilerplate->map()->unused_property_fields());
305 } 317 }
306 318
307 return boilerplate; 319 return boilerplate;
308 } 320 }
309 321
310 322
311 MaybeObject* TransitionElements(Handle<Object> object, 323 MaybeObject* TransitionElements(Handle<Object> object,
312 ElementsKind to_kind, 324 ElementsKind to_kind,
(...skipping 1975 matching lines...) Expand 10 before | Expand all | Expand 10 after
2288 2300
2289 function->set_map(new_map); 2301 function->set_map(new_map);
2290 } else { // Dictionary properties. 2302 } else { // Dictionary properties.
2291 // Directly manipulate the property details. 2303 // Directly manipulate the property details.
2292 int entry = function->property_dictionary()->FindEntry(name); 2304 int entry = function->property_dictionary()->FindEntry(name);
2293 ASSERT(entry != NameDictionary::kNotFound); 2305 ASSERT(entry != NameDictionary::kNotFound);
2294 PropertyDetails details = function->property_dictionary()->DetailsAt(entry); 2306 PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
2295 PropertyDetails new_details( 2307 PropertyDetails new_details(
2296 static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), 2308 static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
2297 details.type(), 2309 details.type(),
2310 Representation::None(),
2298 details.dictionary_index()); 2311 details.dictionary_index());
2299 function->property_dictionary()->DetailsAtPut(entry, new_details); 2312 function->property_dictionary()->DetailsAtPut(entry, new_details);
2300 } 2313 }
2301 return function; 2314 return function;
2302 } 2315 }
2303 2316
2304 2317
2305 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) { 2318 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) {
2306 NoHandleAllocation ha(isolate); 2319 NoHandleAllocation ha(isolate);
2307 ASSERT(args.length() == 1); 2320 ASSERT(args.length() == 1);
(...skipping 5168 matching lines...) Expand 10 before | Expand all | Expand 10 after
7476 Execution::New(Handle<JSFunction>::cast(bound_function), 7489 Execution::New(Handle<JSFunction>::cast(bound_function),
7477 total_argc, *param_data, &exception); 7490 total_argc, *param_data, &exception);
7478 if (exception) { 7491 if (exception) {
7479 return Failure::Exception(); 7492 return Failure::Exception();
7480 } 7493 }
7481 ASSERT(!result.is_null()); 7494 ASSERT(!result.is_null());
7482 return *result; 7495 return *result;
7483 } 7496 }
7484 7497
7485 7498
7486 static void TrySettingInlineConstructStub(Isolate* isolate, 7499 // static void TrySettingInlineConstructStub(Isolate* isolate,
7487 Handle<JSFunction> function) { 7500 // Handle<JSFunction> function) {
7488 Handle<Object> prototype = isolate->factory()->null_value(); 7501 // Handle<Object> prototype = isolate->factory()->null_value();
7489 if (function->has_instance_prototype()) { 7502 // if (function->has_instance_prototype()) {
7490 prototype = Handle<Object>(function->instance_prototype(), isolate); 7503 // prototype = Handle<Object>(function->instance_prototype(), isolate);
7491 } 7504 // }
7492 if (function->shared()->CanGenerateInlineConstructor(*prototype)) { 7505 // if (function->shared()->CanGenerateInlineConstructor(*prototype)) {
7493 ConstructStubCompiler compiler(isolate); 7506 // ConstructStubCompiler compiler(isolate);
7494 Handle<Code> code = compiler.CompileConstructStub(function); 7507 // Handle<Code> code = compiler.CompileConstructStub(function);
7495 function->shared()->set_construct_stub(*code); 7508 // function->shared()->set_construct_stub(*code);
7496 } 7509 // }
7497 } 7510 // }
7498 7511
7499 7512
7500 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) { 7513 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) {
7501 HandleScope scope(isolate); 7514 HandleScope scope(isolate);
7502 ASSERT(args.length() == 1); 7515 ASSERT(args.length() == 1);
7503 7516
7504 Handle<Object> constructor = args.at<Object>(0); 7517 Handle<Object> constructor = args.at<Object>(0);
7505 7518
7506 // If the constructor isn't a proper function we throw a type error. 7519 // If the constructor isn't a proper function we throw a type error.
7507 if (!constructor->IsJSFunction()) { 7520 if (!constructor->IsJSFunction()) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
7553 7566
7554 Handle<SharedFunctionInfo> shared(function->shared(), isolate); 7567 Handle<SharedFunctionInfo> shared(function->shared(), isolate);
7555 if (!function->has_initial_map() && 7568 if (!function->has_initial_map() &&
7556 shared->IsInobjectSlackTrackingInProgress()) { 7569 shared->IsInobjectSlackTrackingInProgress()) {
7557 // The tracking is already in progress for another function. We can only 7570 // The tracking is already in progress for another function. We can only
7558 // track one initial_map at a time, so we force the completion before the 7571 // track one initial_map at a time, so we force the completion before the
7559 // function is called as a constructor for the first time. 7572 // function is called as a constructor for the first time.
7560 shared->CompleteInobjectSlackTracking(); 7573 shared->CompleteInobjectSlackTracking();
7561 } 7574 }
7562 7575
7563 bool first_allocation = !shared->live_objects_may_exist(); 7576 // bool first_allocation = !shared->live_objects_may_exist();
7564 Handle<JSObject> result = isolate->factory()->NewJSObject(function); 7577 Handle<JSObject> result = isolate->factory()->NewJSObject(function);
7565 RETURN_IF_EMPTY_HANDLE(isolate, result); 7578 RETURN_IF_EMPTY_HANDLE(isolate, result);
7566 // Delay setting the stub if inobject slack tracking is in progress. 7579 // Delay setting the stub if inobject slack tracking is in progress.
7567 if (first_allocation && !shared->IsInobjectSlackTrackingInProgress()) { 7580 // if (first_allocation && !shared->IsInobjectSlackTrackingInProgress()) {
7568 TrySettingInlineConstructStub(isolate, function); 7581 // TrySettingInlineConstructStub(isolate, function);
7569 } 7582 // }
7570 7583
7571 isolate->counters()->constructed_objects()->Increment(); 7584 isolate->counters()->constructed_objects()->Increment();
7572 isolate->counters()->constructed_objects_runtime()->Increment(); 7585 isolate->counters()->constructed_objects_runtime()->Increment();
7573 7586
7574 return *result; 7587 return *result;
7575 } 7588 }
7576 7589
7577 7590
7578 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinalizeInstanceSize) { 7591 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinalizeInstanceSize) {
7579 HandleScope scope(isolate); 7592 HandleScope scope(isolate);
7580 ASSERT(args.length() == 1); 7593 ASSERT(args.length() == 1);
7581 7594
7582 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 7595 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
7583 function->shared()->CompleteInobjectSlackTracking(); 7596 function->shared()->CompleteInobjectSlackTracking();
7584 TrySettingInlineConstructStub(isolate, function); 7597 // TrySettingInlineConstructStub(isolate, function);
7585 7598
7586 return isolate->heap()->undefined_value(); 7599 return isolate->heap()->undefined_value();
7587 } 7600 }
7588 7601
7589 7602
7590 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyCompile) { 7603 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyCompile) {
7591 HandleScope scope(isolate); 7604 HandleScope scope(isolate);
7592 ASSERT(args.length() == 1); 7605 ASSERT(args.length() == 1);
7593 7606
7594 Handle<JSFunction> function = args.at<JSFunction>(0); 7607 Handle<JSFunction> function = args.at<JSFunction>(0);
(...skipping 2455 matching lines...) Expand 10 before | Expand all | Expand 10 after
10050 if (name->AsArrayIndex(&index)) { 10063 if (name->AsArrayIndex(&index)) {
10051 Handle<FixedArray> details = isolate->factory()->NewFixedArray(2); 10064 Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
10052 Object* element_or_char; 10065 Object* element_or_char;
10053 { MaybeObject* maybe_element_or_char = 10066 { MaybeObject* maybe_element_or_char =
10054 Runtime::GetElementOrCharAt(isolate, obj, index); 10067 Runtime::GetElementOrCharAt(isolate, obj, index);
10055 if (!maybe_element_or_char->ToObject(&element_or_char)) { 10068 if (!maybe_element_or_char->ToObject(&element_or_char)) {
10056 return maybe_element_or_char; 10069 return maybe_element_or_char;
10057 } 10070 }
10058 } 10071 }
10059 details->set(0, element_or_char); 10072 details->set(0, element_or_char);
10060 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); 10073 details->set(
10074 1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
10061 return *isolate->factory()->NewJSArrayWithElements(details); 10075 return *isolate->factory()->NewJSArrayWithElements(details);
10062 } 10076 }
10063 10077
10064 // Find the number of objects making up this. 10078 // Find the number of objects making up this.
10065 int length = LocalPrototypeChainLength(*obj); 10079 int length = LocalPrototypeChainLength(*obj);
10066 10080
10067 // Try local lookup on each of the objects. 10081 // Try local lookup on each of the objects.
10068 Handle<JSObject> jsproto = obj; 10082 Handle<JSObject> jsproto = obj;
10069 for (int i = 0; i < length; i++) { 10083 for (int i = 0; i < length; i++) {
10070 LookupResult result(isolate); 10084 LookupResult result(isolate);
(...skipping 3168 matching lines...) Expand 10 before | Expand all | Expand 10 after
13239 for (int i = 0; i < kNumFunctions; ++i) { 13253 for (int i = 0; i < kNumFunctions; ++i) {
13240 Object* name_string; 13254 Object* name_string;
13241 { MaybeObject* maybe_name_string = 13255 { MaybeObject* maybe_name_string =
13242 heap->InternalizeUtf8String(kIntrinsicFunctions[i].name); 13256 heap->InternalizeUtf8String(kIntrinsicFunctions[i].name);
13243 if (!maybe_name_string->ToObject(&name_string)) return maybe_name_string; 13257 if (!maybe_name_string->ToObject(&name_string)) return maybe_name_string;
13244 } 13258 }
13245 NameDictionary* name_dictionary = NameDictionary::cast(dictionary); 13259 NameDictionary* name_dictionary = NameDictionary::cast(dictionary);
13246 { MaybeObject* maybe_dictionary = name_dictionary->Add( 13260 { MaybeObject* maybe_dictionary = name_dictionary->Add(
13247 String::cast(name_string), 13261 String::cast(name_string),
13248 Smi::FromInt(i), 13262 Smi::FromInt(i),
13249 PropertyDetails(NONE, NORMAL)); 13263 PropertyDetails(NONE, NORMAL, Representation::None()));
13250 if (!maybe_dictionary->ToObject(&dictionary)) { 13264 if (!maybe_dictionary->ToObject(&dictionary)) {
13251 // Non-recoverable failure. Calling code must restart heap 13265 // Non-recoverable failure. Calling code must restart heap
13252 // initialization. 13266 // initialization.
13253 return maybe_dictionary; 13267 return maybe_dictionary;
13254 } 13268 }
13255 } 13269 }
13256 } 13270 }
13257 return dictionary; 13271 return dictionary;
13258 } 13272 }
13259 13273
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
13291 // Handle last resort GC and make sure to allow future allocations 13305 // Handle last resort GC and make sure to allow future allocations
13292 // to grow the heap without causing GCs (if possible). 13306 // to grow the heap without causing GCs (if possible).
13293 isolate->counters()->gc_last_resort_from_js()->Increment(); 13307 isolate->counters()->gc_last_resort_from_js()->Increment();
13294 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13308 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13295 "Runtime::PerformGC"); 13309 "Runtime::PerformGC");
13296 } 13310 }
13297 } 13311 }
13298 13312
13299 13313
13300 } } // namespace v8::internal 13314 } } // namespace v8::internal
OLDNEW
« src/objects-inl.h ('K') | « src/property-details.h ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698