| OLD | NEW |
| 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 Loading... |
| 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): Support tracking representations in the boilerplate. |
| 252 for (int index = 0; index < length; index +=2) { | 253 for (int index = 0; index < length; index +=2) { |
| 253 Handle<Object> key(constant_properties->get(index+0), isolate); | 254 Handle<Object> key(constant_properties->get(index+0), isolate); |
| 254 Handle<Object> value(constant_properties->get(index+1), isolate); | 255 Handle<Object> value(constant_properties->get(index+1), isolate); |
| 255 if (value->IsFixedArray()) { | 256 if (value->IsFixedArray()) { |
| 256 // The value contains the constant_properties of a | 257 // The value contains the constant_properties of a |
| 257 // simple object or array literal. | 258 // simple object or array literal. |
| 258 Handle<FixedArray> array = Handle<FixedArray>::cast(value); | 259 Handle<FixedArray> array = Handle<FixedArray>::cast(value); |
| 259 value = CreateLiteralBoilerplate(isolate, literals, array); | 260 value = CreateLiteralBoilerplate(isolate, literals, array); |
| 260 if (value.is_null()) return value; | 261 if (value.is_null()) return value; |
| 261 } | 262 } |
| (...skipping 2026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2288 | 2289 |
| 2289 function->set_map(new_map); | 2290 function->set_map(new_map); |
| 2290 } else { // Dictionary properties. | 2291 } else { // Dictionary properties. |
| 2291 // Directly manipulate the property details. | 2292 // Directly manipulate the property details. |
| 2292 int entry = function->property_dictionary()->FindEntry(name); | 2293 int entry = function->property_dictionary()->FindEntry(name); |
| 2293 ASSERT(entry != NameDictionary::kNotFound); | 2294 ASSERT(entry != NameDictionary::kNotFound); |
| 2294 PropertyDetails details = function->property_dictionary()->DetailsAt(entry); | 2295 PropertyDetails details = function->property_dictionary()->DetailsAt(entry); |
| 2295 PropertyDetails new_details( | 2296 PropertyDetails new_details( |
| 2296 static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), | 2297 static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), |
| 2297 details.type(), | 2298 details.type(), |
| 2299 Representation::None(), |
| 2298 details.dictionary_index()); | 2300 details.dictionary_index()); |
| 2299 function->property_dictionary()->DetailsAtPut(entry, new_details); | 2301 function->property_dictionary()->DetailsAtPut(entry, new_details); |
| 2300 } | 2302 } |
| 2301 return function; | 2303 return function; |
| 2302 } | 2304 } |
| 2303 | 2305 |
| 2304 | 2306 |
| 2305 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) { | 2307 RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) { |
| 2306 NoHandleAllocation ha(isolate); | 2308 NoHandleAllocation ha(isolate); |
| 2307 ASSERT(args.length() == 1); | 2309 ASSERT(args.length() == 1); |
| (...skipping 5168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7476 Execution::New(Handle<JSFunction>::cast(bound_function), | 7478 Execution::New(Handle<JSFunction>::cast(bound_function), |
| 7477 total_argc, *param_data, &exception); | 7479 total_argc, *param_data, &exception); |
| 7478 if (exception) { | 7480 if (exception) { |
| 7479 return Failure::Exception(); | 7481 return Failure::Exception(); |
| 7480 } | 7482 } |
| 7481 ASSERT(!result.is_null()); | 7483 ASSERT(!result.is_null()); |
| 7482 return *result; | 7484 return *result; |
| 7483 } | 7485 } |
| 7484 | 7486 |
| 7485 | 7487 |
| 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) { | 7488 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewObject) { |
| 7501 HandleScope scope(isolate); | 7489 HandleScope scope(isolate); |
| 7502 ASSERT(args.length() == 1); | 7490 ASSERT(args.length() == 1); |
| 7503 | 7491 |
| 7504 Handle<Object> constructor = args.at<Object>(0); | 7492 Handle<Object> constructor = args.at<Object>(0); |
| 7505 | 7493 |
| 7506 // If the constructor isn't a proper function we throw a type error. | 7494 // If the constructor isn't a proper function we throw a type error. |
| 7507 if (!constructor->IsJSFunction()) { | 7495 if (!constructor->IsJSFunction()) { |
| 7508 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); | 7496 Vector< Handle<Object> > arguments = HandleVector(&constructor, 1); |
| 7509 Handle<Object> type_error = | 7497 Handle<Object> type_error = |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7553 | 7541 |
| 7554 Handle<SharedFunctionInfo> shared(function->shared(), isolate); | 7542 Handle<SharedFunctionInfo> shared(function->shared(), isolate); |
| 7555 if (!function->has_initial_map() && | 7543 if (!function->has_initial_map() && |
| 7556 shared->IsInobjectSlackTrackingInProgress()) { | 7544 shared->IsInobjectSlackTrackingInProgress()) { |
| 7557 // The tracking is already in progress for another function. We can only | 7545 // 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 | 7546 // 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. | 7547 // function is called as a constructor for the first time. |
| 7560 shared->CompleteInobjectSlackTracking(); | 7548 shared->CompleteInobjectSlackTracking(); |
| 7561 } | 7549 } |
| 7562 | 7550 |
| 7563 bool first_allocation = !shared->live_objects_may_exist(); | |
| 7564 Handle<JSObject> result = isolate->factory()->NewJSObject(function); | 7551 Handle<JSObject> result = isolate->factory()->NewJSObject(function); |
| 7565 RETURN_IF_EMPTY_HANDLE(isolate, result); | 7552 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 | 7553 |
| 7571 isolate->counters()->constructed_objects()->Increment(); | 7554 isolate->counters()->constructed_objects()->Increment(); |
| 7572 isolate->counters()->constructed_objects_runtime()->Increment(); | 7555 isolate->counters()->constructed_objects_runtime()->Increment(); |
| 7573 | 7556 |
| 7574 return *result; | 7557 return *result; |
| 7575 } | 7558 } |
| 7576 | 7559 |
| 7577 | 7560 |
| 7578 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinalizeInstanceSize) { | 7561 RUNTIME_FUNCTION(MaybeObject*, Runtime_FinalizeInstanceSize) { |
| 7579 HandleScope scope(isolate); | 7562 HandleScope scope(isolate); |
| 7580 ASSERT(args.length() == 1); | 7563 ASSERT(args.length() == 1); |
| 7581 | 7564 |
| 7582 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); | 7565 CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0); |
| 7583 function->shared()->CompleteInobjectSlackTracking(); | 7566 function->shared()->CompleteInobjectSlackTracking(); |
| 7584 TrySettingInlineConstructStub(isolate, function); | |
| 7585 | 7567 |
| 7586 return isolate->heap()->undefined_value(); | 7568 return isolate->heap()->undefined_value(); |
| 7587 } | 7569 } |
| 7588 | 7570 |
| 7589 | 7571 |
| 7590 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyCompile) { | 7572 RUNTIME_FUNCTION(MaybeObject*, Runtime_LazyCompile) { |
| 7591 HandleScope scope(isolate); | 7573 HandleScope scope(isolate); |
| 7592 ASSERT(args.length() == 1); | 7574 ASSERT(args.length() == 1); |
| 7593 | 7575 |
| 7594 Handle<JSFunction> function = args.at<JSFunction>(0); | 7576 Handle<JSFunction> function = args.at<JSFunction>(0); |
| (...skipping 2455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10050 if (name->AsArrayIndex(&index)) { | 10032 if (name->AsArrayIndex(&index)) { |
| 10051 Handle<FixedArray> details = isolate->factory()->NewFixedArray(2); | 10033 Handle<FixedArray> details = isolate->factory()->NewFixedArray(2); |
| 10052 Object* element_or_char; | 10034 Object* element_or_char; |
| 10053 { MaybeObject* maybe_element_or_char = | 10035 { MaybeObject* maybe_element_or_char = |
| 10054 Runtime::GetElementOrCharAt(isolate, obj, index); | 10036 Runtime::GetElementOrCharAt(isolate, obj, index); |
| 10055 if (!maybe_element_or_char->ToObject(&element_or_char)) { | 10037 if (!maybe_element_or_char->ToObject(&element_or_char)) { |
| 10056 return maybe_element_or_char; | 10038 return maybe_element_or_char; |
| 10057 } | 10039 } |
| 10058 } | 10040 } |
| 10059 details->set(0, element_or_char); | 10041 details->set(0, element_or_char); |
| 10060 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); | 10042 details->set( |
| 10043 1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi()); |
| 10061 return *isolate->factory()->NewJSArrayWithElements(details); | 10044 return *isolate->factory()->NewJSArrayWithElements(details); |
| 10062 } | 10045 } |
| 10063 | 10046 |
| 10064 // Find the number of objects making up this. | 10047 // Find the number of objects making up this. |
| 10065 int length = LocalPrototypeChainLength(*obj); | 10048 int length = LocalPrototypeChainLength(*obj); |
| 10066 | 10049 |
| 10067 // Try local lookup on each of the objects. | 10050 // Try local lookup on each of the objects. |
| 10068 Handle<JSObject> jsproto = obj; | 10051 Handle<JSObject> jsproto = obj; |
| 10069 for (int i = 0; i < length; i++) { | 10052 for (int i = 0; i < length; i++) { |
| 10070 LookupResult result(isolate); | 10053 LookupResult result(isolate); |
| (...skipping 3168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13239 for (int i = 0; i < kNumFunctions; ++i) { | 13222 for (int i = 0; i < kNumFunctions; ++i) { |
| 13240 Object* name_string; | 13223 Object* name_string; |
| 13241 { MaybeObject* maybe_name_string = | 13224 { MaybeObject* maybe_name_string = |
| 13242 heap->InternalizeUtf8String(kIntrinsicFunctions[i].name); | 13225 heap->InternalizeUtf8String(kIntrinsicFunctions[i].name); |
| 13243 if (!maybe_name_string->ToObject(&name_string)) return maybe_name_string; | 13226 if (!maybe_name_string->ToObject(&name_string)) return maybe_name_string; |
| 13244 } | 13227 } |
| 13245 NameDictionary* name_dictionary = NameDictionary::cast(dictionary); | 13228 NameDictionary* name_dictionary = NameDictionary::cast(dictionary); |
| 13246 { MaybeObject* maybe_dictionary = name_dictionary->Add( | 13229 { MaybeObject* maybe_dictionary = name_dictionary->Add( |
| 13247 String::cast(name_string), | 13230 String::cast(name_string), |
| 13248 Smi::FromInt(i), | 13231 Smi::FromInt(i), |
| 13249 PropertyDetails(NONE, NORMAL)); | 13232 PropertyDetails(NONE, NORMAL, Representation::None())); |
| 13250 if (!maybe_dictionary->ToObject(&dictionary)) { | 13233 if (!maybe_dictionary->ToObject(&dictionary)) { |
| 13251 // Non-recoverable failure. Calling code must restart heap | 13234 // Non-recoverable failure. Calling code must restart heap |
| 13252 // initialization. | 13235 // initialization. |
| 13253 return maybe_dictionary; | 13236 return maybe_dictionary; |
| 13254 } | 13237 } |
| 13255 } | 13238 } |
| 13256 } | 13239 } |
| 13257 return dictionary; | 13240 return dictionary; |
| 13258 } | 13241 } |
| 13259 | 13242 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13291 // Handle last resort GC and make sure to allow future allocations | 13274 // Handle last resort GC and make sure to allow future allocations |
| 13292 // to grow the heap without causing GCs (if possible). | 13275 // to grow the heap without causing GCs (if possible). |
| 13293 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13276 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13294 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13277 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 13295 "Runtime::PerformGC"); | 13278 "Runtime::PerformGC"); |
| 13296 } | 13279 } |
| 13297 } | 13280 } |
| 13298 | 13281 |
| 13299 | 13282 |
| 13300 } } // namespace v8::internal | 13283 } } // namespace v8::internal |
| OLD | NEW |