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

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: X64 port Created 7 years, 8 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
danno 2013/04/25 13:33:48 Elaborate, please :-) (fast)
Toon Verwaest 2013/04/25 14:49:10 Done.
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 tracking representations in the boilerplate.
danno 2013/04/25 13:33:48 Remove all this code, insert TODO
Toon Verwaest 2013/04/25 14:49:10 Done.
261 } 268 }
262 Handle<Object> result; 269 Handle<Object> result;
263 uint32_t element_index = 0; 270 uint32_t element_index = 0;
264 if (key->IsInternalizedString()) { 271 if (key->IsInternalizedString()) {
265 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) { 272 if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
266 // Array index as string (uint32). 273 // Array index as string (uint32).
267 result = JSObject::SetOwnElement( 274 result = JSObject::SetOwnElement(
268 boilerplate, element_index, value, kNonStrictMode); 275 boilerplate, element_index, value, kNonStrictMode);
269 } else { 276 } else {
270 Handle<String> name(String::cast(*key)); 277 Handle<String> name(String::cast(*key));
(...skipping 21 matching lines...) Expand all
292 // exception, the exception is converted to an empty handle in 299 // exception, the exception is converted to an empty handle in
293 // the handle based operations. In that case, we need to 300 // the handle based operations. In that case, we need to
294 // convert back to an exception. 301 // convert back to an exception.
295 if (result.is_null()) return result; 302 if (result.is_null()) return result;
296 } 303 }
297 304
298 // Transform to fast properties if necessary. For object literals with 305 // Transform to fast properties if necessary. For object literals with
299 // containing function literals we defer this operation until after all 306 // containing function literals we defer this operation until after all
300 // computed properties have been assigned so that we can generate 307 // computed properties have been assigned so that we can generate
301 // constant function properties. 308 // constant function properties.
302 if (should_transform && !has_function_literal) { 309 if (will_be_fast) {
303 JSObject::TransformToFastProperties( 310 JSObject::TransformToFastProperties(
304 boilerplate, boilerplate->map()->unused_property_fields()); 311 boilerplate, boilerplate->map()->unused_property_fields());
305 } 312 }
306 313
307 return boilerplate; 314 return boilerplate;
308 } 315 }
309 316
310 317
311 MaybeObject* TransitionElements(Handle<Object> object, 318 MaybeObject* TransitionElements(Handle<Object> object,
312 ElementsKind to_kind, 319 ElementsKind to_kind,
(...skipping 1975 matching lines...) Expand 10 before | Expand all | Expand 10 after
2288 2295
2289 function->set_map(new_map); 2296 function->set_map(new_map);
2290 } else { // Dictionary properties. 2297 } else { // Dictionary properties.
2291 // Directly manipulate the property details. 2298 // Directly manipulate the property details.
2292 int entry = function->property_dictionary()->FindEntry(name); 2299 int entry = function->property_dictionary()->FindEntry(name);
2293 ASSERT(entry != NameDictionary::kNotFound); 2300 ASSERT(entry != NameDictionary::kNotFound);
2294 PropertyDetails details = function->property_dictionary()->DetailsAt(entry); 2301 PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
2295 PropertyDetails new_details( 2302 PropertyDetails new_details(
2296 static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), 2303 static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
2297 details.type(), 2304 details.type(),
2305 Representation::None(),
2298 details.dictionary_index()); 2306 details.dictionary_index());
2299 function->property_dictionary()->DetailsAtPut(entry, new_details); 2307 function->property_dictionary()->DetailsAtPut(entry, new_details);
2300 } 2308 }
2301 return function; 2309 return function;
2302 } 2310 }
2303 2311
2304 2312
2305 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) { 2313 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) {
2306 NoHandleAllocation ha(isolate); 2314 NoHandleAllocation ha(isolate);
2307 ASSERT(args.length() == 1); 2315 ASSERT(args.length() == 1);
(...skipping 5168 matching lines...) Expand 10 before | Expand all | Expand 10 after
7476 Execution::New(Handle<JSFunction>::cast(bound_function), 7484 Execution::New(Handle<JSFunction>::cast(bound_function),
7477 total_argc, *param_data, &exception); 7485 total_argc, *param_data, &exception);
7478 if (exception) { 7486 if (exception) {
7479 return Failure::Exception(); 7487 return Failure::Exception();
7480 } 7488 }
7481 ASSERT(!result.is_null()); 7489 ASSERT(!result.is_null());
7482 return *result; 7490 return *result;
7483 } 7491 }
7484 7492
7485 7493
7486 static void TrySettingInlineConstructStub(Isolate* isolate,
7487 Handle<JSFunction> function) {
7488 Handle<Object> prototype = isolate->factory()->null_value();
7489 if (function->has_instance_prototype()) {
7490 prototype = Handle<Object>(function->instance_prototype(), isolate);
7491 }
7492 if (function->shared()->CanGenerateInlineConstructor(*prototype)) {
7493 ConstructStubCompiler compiler(isolate);
7494 Handle<Code> code = compiler.CompileConstructStub(function);
7495 function->shared()->set_construct_stub(*code);
7496 }
7497 }
7498
7499
7500 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) { 7494 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) {
7501 HandleScope scope(isolate); 7495 HandleScope scope(isolate);
7502 ASSERT(args.length() == 1); 7496 ASSERT(args.length() == 1);
7503 7497
7504 Handle<Object> constructor = args.at<Object>(0); 7498 Handle<Object> constructor = args.at<Object>(0);
7505 7499
7506 // If the constructor isn't a proper function we throw a type error. 7500 // If the constructor isn't a proper function we throw a type error.
7507 if (!constructor->IsJSFunction()) { 7501 if (!constructor->IsJSFunction()) {
7508 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); 7502 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
7509 Handle<Object> type_error = 7503 Handle<Object> type_error =
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
7553 7547
7554 Handle<SharedFunctionInfo> shared(function->shared(), isolate); 7548 Handle<SharedFunctionInfo> shared(function->shared(), isolate);
7555 if (!function->has_initial_map() && 7549 if (!function->has_initial_map() &&
7556 shared->IsInobjectSlackTrackingInProgress()) { 7550 shared->IsInobjectSlackTrackingInProgress()) {
7557 // The tracking is already in progress for another function. We can only 7551 // 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 7552 // 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. 7553 // function is called as a constructor for the first time.
7560 shared->CompleteInobjectSlackTracking(); 7554 shared->CompleteInobjectSlackTracking();
7561 } 7555 }
7562 7556
7563 bool first_allocation = !shared->live_objects_may_exist();
7564 Handle<JSObject> result = isolate->factory()->NewJSObject(function); 7557 Handle<JSObject> result = isolate->factory()->NewJSObject(function);
7565 RETURN_IF_EMPTY_HANDLE(isolate, result); 7558 RETURN_IF_EMPTY_HANDLE(isolate, result);
7566 // Delay setting the stub if inobject slack tracking is in progress.
7567 if (first_allocation && !shared->IsInobjectSlackTrackingInProgress()) {
7568 TrySettingInlineConstructStub(isolate, function);
7569 }
7570 7559
7571 isolate->counters()->constructed_objects()->Increment(); 7560 isolate->counters()->constructed_objects()->Increment();
7572 isolate->counters()->constructed_objects_runtime()->Increment(); 7561 isolate->counters()->constructed_objects_runtime()->Increment();
7573 7562
7574 return *result; 7563 return *result;
7575 } 7564 }
7576 7565
7577 7566
7578 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinalizeInstanceSize) { 7567 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinalizeInstanceSize) {
7579 HandleScope scope(isolate); 7568 HandleScope scope(isolate);
7580 ASSERT(args.length() == 1); 7569 ASSERT(args.length() == 1);
7581 7570
7582 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); 7571 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
7583 function->shared()->CompleteInobjectSlackTracking(); 7572 function->shared()->CompleteInobjectSlackTracking();
7584 TrySettingInlineConstructStub(isolate, function);
7585 7573
7586 return isolate->heap()->undefined_value(); 7574 return isolate->heap()->undefined_value();
7587 } 7575 }
7588 7576
7589 7577
7590 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyCompile) { 7578 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyCompile) {
7591 HandleScope scope(isolate); 7579 HandleScope scope(isolate);
7592 ASSERT(args.length() == 1); 7580 ASSERT(args.length() == 1);
7593 7581
7594 Handle<JSFunction> function = args.at<JSFunction>(0); 7582 Handle<JSFunction> function = args.at<JSFunction>(0);
(...skipping 2455 matching lines...) Expand 10 before | Expand all | Expand 10 after
10050 if (name->AsArrayIndex(&index)) { 10038 if (name->AsArrayIndex(&index)) {
10051 Handle<FixedArray> details = isolate->factory()->NewFixedArray(2); 10039 Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
10052 Object* element_or_char; 10040 Object* element_or_char;
10053 { MaybeObject* maybe_element_or_char = 10041 { MaybeObject* maybe_element_or_char =
10054 Runtime::GetElementOrCharAt(isolate, obj, index); 10042 Runtime::GetElementOrCharAt(isolate, obj, index);
10055 if (!maybe_element_or_char->ToObject(&element_or_char)) { 10043 if (!maybe_element_or_char->ToObject(&element_or_char)) {
10056 return maybe_element_or_char; 10044 return maybe_element_or_char;
10057 } 10045 }
10058 } 10046 }
10059 details->set(0, element_or_char); 10047 details->set(0, element_or_char);
10060 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); 10048 details->set(
10049 1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
10061 return *isolate->factory()->NewJSArrayWithElements(details); 10050 return *isolate->factory()->NewJSArrayWithElements(details);
10062 } 10051 }
10063 10052
10064 // Find the number of objects making up this. 10053 // Find the number of objects making up this.
10065 int length = LocalPrototypeChainLength(*obj); 10054 int length = LocalPrototypeChainLength(*obj);
10066 10055
10067 // Try local lookup on each of the objects. 10056 // Try local lookup on each of the objects.
10068 Handle<JSObject> jsproto = obj; 10057 Handle<JSObject> jsproto = obj;
10069 for (int i = 0; i < length; i++) { 10058 for (int i = 0; i < length; i++) {
10070 LookupResult result(isolate); 10059 LookupResult result(isolate);
(...skipping 3168 matching lines...) Expand 10 before | Expand all | Expand 10 after
13239 for (int i = 0; i < kNumFunctions; ++i) { 13228 for (int i = 0; i < kNumFunctions; ++i) {
13240 Object* name_string; 13229 Object* name_string;
13241 { MaybeObject* maybe_name_string = 13230 { MaybeObject* maybe_name_string =
13242 heap->InternalizeUtf8String(kIntrinsicFunctions[i].name); 13231 heap->InternalizeUtf8String(kIntrinsicFunctions[i].name);
13243 if (!maybe_name_string->ToObject(&name_string)) return maybe_name_string; 13232 if (!maybe_name_string->ToObject(&name_string)) return maybe_name_string;
13244 } 13233 }
13245 NameDictionary* name_dictionary = NameDictionary::cast(dictionary); 13234 NameDictionary* name_dictionary = NameDictionary::cast(dictionary);
13246 { MaybeObject* maybe_dictionary = name_dictionary->Add( 13235 { MaybeObject* maybe_dictionary = name_dictionary->Add(
13247 String::cast(name_string), 13236 String::cast(name_string),
13248 Smi::FromInt(i), 13237 Smi::FromInt(i),
13249 PropertyDetails(NONE, NORMAL)); 13238 PropertyDetails(NONE, NORMAL, Representation::None()));
13250 if (!maybe_dictionary->ToObject(&dictionary)) { 13239 if (!maybe_dictionary->ToObject(&dictionary)) {
13251 // Non-recoverable failure. Calling code must restart heap 13240 // Non-recoverable failure. Calling code must restart heap
13252 // initialization. 13241 // initialization.
13253 return maybe_dictionary; 13242 return maybe_dictionary;
13254 } 13243 }
13255 } 13244 }
13256 } 13245 }
13257 return dictionary; 13246 return dictionary;
13258 } 13247 }
13259 13248
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
13291 // Handle last resort GC and make sure to allow future allocations 13280 // Handle last resort GC and make sure to allow future allocations
13292 // to grow the heap without causing GCs (if possible). 13281 // to grow the heap without causing GCs (if possible).
13293 isolate->counters()->gc_last_resort_from_js()->Increment(); 13282 isolate->counters()->gc_last_resort_from_js()->Increment();
13294 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13283 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13295 "Runtime::PerformGC"); 13284 "Runtime::PerformGC");
13296 } 13285 }
13297 } 13286 }
13298 13287
13299 13288
13300 } } // namespace v8::internal 13289 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698