| 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 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 } | 255 } |
| 256 } | 256 } |
| 257 | 257 |
| 258 | 258 |
| 259 bool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property* property) { | 259 bool ObjectLiteral::IsBoilerplateProperty(ObjectLiteral::Property* property) { |
| 260 return property != NULL && | 260 return property != NULL && |
| 261 property->kind() != ObjectLiteral::Property::PROTOTYPE; | 261 property->kind() != ObjectLiteral::Property::PROTOTYPE; |
| 262 } | 262 } |
| 263 | 263 |
| 264 | 264 |
| 265 void ObjectLiteral::BuildConstantProperties(Isolate* isolate, int* depth) { | 265 void ObjectLiteral::BuildConstantProperties(Isolate* isolate) { |
| 266 if (!constant_properties_.is_null()) return; | 266 if (!constant_properties_.is_null()) return; |
| 267 | 267 |
| 268 // Allocate a fixed array to hold all the constant properties. | 268 // Allocate a fixed array to hold all the constant properties. |
| 269 Handle<FixedArray> constant_properties = isolate->factory()->NewFixedArray( | 269 Handle<FixedArray> constant_properties = isolate->factory()->NewFixedArray( |
| 270 boilerplate_properties_ * 2, TENURED); | 270 boilerplate_properties_ * 2, TENURED); |
| 271 | 271 |
| 272 int position = 0; | 272 int position = 0; |
| 273 // Accumulate the value in local variables and store it at the end. | 273 // Accumulate the value in local variables and store it at the end. |
| 274 bool is_simple = true; | 274 bool is_simple = true; |
| 275 int depth_acc = 1; | 275 int depth_acc = 1; |
| 276 uint32_t max_element_index = 0; | 276 uint32_t max_element_index = 0; |
| 277 uint32_t elements = 0; | 277 uint32_t elements = 0; |
| 278 for (int i = 0; i < properties()->length(); i++) { | 278 for (int i = 0; i < properties()->length(); i++) { |
| 279 ObjectLiteral::Property* property = properties()->at(i); | 279 ObjectLiteral::Property* property = properties()->at(i); |
| 280 if (!IsBoilerplateProperty(property)) { | 280 if (!IsBoilerplateProperty(property)) { |
| 281 is_simple = false; | 281 is_simple = false; |
| 282 continue; | 282 continue; |
| 283 } | 283 } |
| 284 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral(); | 284 MaterializedLiteral* m_literal = property->value()->AsMaterializedLiteral(); |
| 285 if (m_literal != NULL) { | 285 if (m_literal != NULL) { |
| 286 int inner_depth = 1; | 286 m_literal->BuildConstants(isolate); |
| 287 m_literal->BuildConstants(isolate, &inner_depth); | 287 if (m_literal->depth() >= depth_acc) depth_acc = m_literal->depth() + 1; |
| 288 if (inner_depth >= depth_acc) depth_acc = inner_depth + 1; | |
| 289 } | 288 } |
| 290 | 289 |
| 291 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined | 290 // Add CONSTANT and COMPUTED properties to boilerplate. Use undefined |
| 292 // value for COMPUTED properties, the real value is filled in at | 291 // value for COMPUTED properties, the real value is filled in at |
| 293 // runtime. The enumeration order is maintained. | 292 // runtime. The enumeration order is maintained. |
| 294 Handle<Object> key = property->key()->value(); | 293 Handle<Object> key = property->key()->value(); |
| 295 Handle<Object> value = GetBoilerplateValue(property->value(), isolate); | 294 Handle<Object> value = GetBoilerplateValue(property->value(), isolate); |
| 296 | 295 |
| 297 // Ensure objects that may, at any point in time, contain fields with double | 296 // Ensure objects that may, at any point in time, contain fields with double |
| 298 // representation are always treated as nested objects. This is true for | 297 // representation are always treated as nested objects. This is true for |
| (...skipping 28 matching lines...) Expand all Loading... |
| 327 | 326 |
| 328 // Add name, value pair to the fixed array. | 327 // Add name, value pair to the fixed array. |
| 329 constant_properties->set(position++, *key); | 328 constant_properties->set(position++, *key); |
| 330 constant_properties->set(position++, *value); | 329 constant_properties->set(position++, *value); |
| 331 } | 330 } |
| 332 | 331 |
| 333 constant_properties_ = constant_properties; | 332 constant_properties_ = constant_properties; |
| 334 fast_elements_ = | 333 fast_elements_ = |
| 335 (max_element_index <= 32) || ((2 * elements) >= max_element_index); | 334 (max_element_index <= 32) || ((2 * elements) >= max_element_index); |
| 336 set_is_simple(is_simple); | 335 set_is_simple(is_simple); |
| 337 if (depth != NULL) *depth = depth_acc; | 336 set_depth(depth_acc); |
| 338 } | 337 } |
| 339 | 338 |
| 340 | 339 |
| 341 void ArrayLiteral::BuildConstantElements(Isolate* isolate, int* depth) { | 340 void ArrayLiteral::BuildConstantElements(Isolate* isolate) { |
| 342 if (!constant_elements_.is_null()) return; | 341 if (!constant_elements_.is_null()) return; |
| 343 | 342 |
| 344 // Allocate a fixed array to hold all the object literals. | 343 // Allocate a fixed array to hold all the object literals. |
| 345 Handle<JSArray> array = | 344 Handle<JSArray> array = |
| 346 isolate->factory()->NewJSArray(0, FAST_HOLEY_SMI_ELEMENTS); | 345 isolate->factory()->NewJSArray(0, FAST_HOLEY_SMI_ELEMENTS); |
| 347 isolate->factory()->SetElementsCapacityAndLength( | 346 isolate->factory()->SetElementsCapacityAndLength( |
| 348 array, values()->length(), values()->length()); | 347 array, values()->length(), values()->length()); |
| 349 | 348 |
| 350 // Fill in the literals. | 349 // Fill in the literals. |
| 351 bool is_simple = true; | 350 bool is_simple = true; |
| 352 int depth_acc = 1; | 351 int depth_acc = 1; |
| 353 bool is_holey = false; | 352 bool is_holey = false; |
| 354 for (int i = 0, n = values()->length(); i < n; i++) { | 353 for (int i = 0, n = values()->length(); i < n; i++) { |
| 355 Expression* element = values()->at(i); | 354 Expression* element = values()->at(i); |
| 356 MaterializedLiteral* m_literal = element->AsMaterializedLiteral(); | 355 MaterializedLiteral* m_literal = element->AsMaterializedLiteral(); |
| 357 if (m_literal != NULL) { | 356 if (m_literal != NULL) { |
| 358 int inner_depth = 1; | 357 m_literal->BuildConstants(isolate); |
| 359 m_literal->BuildConstants(isolate, &inner_depth); | 358 if (m_literal->depth() + 1 > depth_acc) { |
| 360 if (inner_depth + 1 > depth_acc) depth_acc = inner_depth + 1; | 359 depth_acc = m_literal->depth() + 1; |
| 360 } |
| 361 } | 361 } |
| 362 Handle<Object> boilerplate_value = GetBoilerplateValue(element, isolate); | 362 Handle<Object> boilerplate_value = GetBoilerplateValue(element, isolate); |
| 363 if (boilerplate_value->IsTheHole()) { | 363 if (boilerplate_value->IsTheHole()) { |
| 364 is_holey = true; | 364 is_holey = true; |
| 365 } else if (boilerplate_value->IsUninitialized()) { | 365 } else if (boilerplate_value->IsUninitialized()) { |
| 366 is_simple = false; | 366 is_simple = false; |
| 367 JSObject::SetOwnElement( | 367 JSObject::SetOwnElement( |
| 368 array, i, handle(Smi::FromInt(0), isolate), kNonStrictMode); | 368 array, i, handle(Smi::FromInt(0), isolate), kNonStrictMode); |
| 369 } else { | 369 } else { |
| 370 JSObject::SetOwnElement(array, i, boilerplate_value, kNonStrictMode); | 370 JSObject::SetOwnElement(array, i, boilerplate_value, kNonStrictMode); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 385 Handle<FixedArray> literals = isolate->factory()->NewFixedArray(2, TENURED); | 385 Handle<FixedArray> literals = isolate->factory()->NewFixedArray(2, TENURED); |
| 386 | 386 |
| 387 ElementsKind kind = array->GetElementsKind(); | 387 ElementsKind kind = array->GetElementsKind(); |
| 388 kind = is_holey ? GetHoleyElementsKind(kind) : GetPackedElementsKind(kind); | 388 kind = is_holey ? GetHoleyElementsKind(kind) : GetPackedElementsKind(kind); |
| 389 | 389 |
| 390 literals->set(0, Smi::FromInt(kind)); | 390 literals->set(0, Smi::FromInt(kind)); |
| 391 literals->set(1, *element_values); | 391 literals->set(1, *element_values); |
| 392 | 392 |
| 393 constant_elements_ = literals; | 393 constant_elements_ = literals; |
| 394 set_is_simple(is_simple); | 394 set_is_simple(is_simple); |
| 395 if (depth != NULL) *depth = depth_acc; | 395 set_depth(depth_acc); |
| 396 } | 396 } |
| 397 | 397 |
| 398 | 398 |
| 399 Handle<Object> MaterializedLiteral::GetBoilerplateValue(Expression* expression, | 399 Handle<Object> MaterializedLiteral::GetBoilerplateValue(Expression* expression, |
| 400 Isolate* isolate) { | 400 Isolate* isolate) { |
| 401 if (expression->AsLiteral() != NULL) { | 401 if (expression->AsLiteral() != NULL) { |
| 402 return expression->AsLiteral()->value(); | 402 return expression->AsLiteral()->value(); |
| 403 } | 403 } |
| 404 if (CompileTimeValue::IsCompileTimeValue(expression)) { | 404 if (CompileTimeValue::IsCompileTimeValue(expression)) { |
| 405 return CompileTimeValue::GetValue(isolate, expression); | 405 return CompileTimeValue::GetValue(isolate, expression); |
| 406 } | 406 } |
| 407 return isolate->factory()->uninitialized_value(); | 407 return isolate->factory()->uninitialized_value(); |
| 408 } | 408 } |
| 409 | 409 |
| 410 | 410 |
| 411 void MaterializedLiteral::BuildConstants(Isolate* isolate, int* depth) { | 411 void MaterializedLiteral::BuildConstants(Isolate* isolate) { |
| 412 if (IsArrayLiteral()) { | 412 if (IsArrayLiteral()) { |
| 413 return AsArrayLiteral()->BuildConstantElements(isolate, depth); | 413 return AsArrayLiteral()->BuildConstantElements(isolate); |
| 414 } | 414 } |
| 415 if (IsObjectLiteral()) { | 415 if (IsObjectLiteral()) { |
| 416 return AsObjectLiteral()->BuildConstantProperties(isolate, depth); | 416 return AsObjectLiteral()->BuildConstantProperties(isolate); |
| 417 } | 417 } |
| 418 ASSERT(IsRegExpLiteral()); | 418 ASSERT(IsRegExpLiteral()); |
| 419 ASSERT(depth() >= 1); // Depth should be initialized. |
| 419 } | 420 } |
| 420 | 421 |
| 421 | 422 |
| 422 void TargetCollector::AddTarget(Label* target, Zone* zone) { | 423 void TargetCollector::AddTarget(Label* target, Zone* zone) { |
| 423 // Add the label to the collector, but discard duplicates. | 424 // Add the label to the collector, but discard duplicates. |
| 424 int length = targets_.length(); | 425 int length = targets_.length(); |
| 425 for (int i = 0; i < length; i++) { | 426 for (int i = 0; i < length; i++) { |
| 426 if (targets_[i] == target) return; | 427 if (targets_[i] == target) return; |
| 427 } | 428 } |
| 428 targets_.Add(target, zone); | 429 targets_.Add(target, zone); |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 } | 770 } |
| 770 | 771 |
| 771 | 772 |
| 772 void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle, | 773 void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle, |
| 773 CallKind call_kind) { | 774 CallKind call_kind) { |
| 774 is_monomorphic_ = oracle->CallIsMonomorphic(this); | 775 is_monomorphic_ = oracle->CallIsMonomorphic(this); |
| 775 Property* property = expression()->AsProperty(); | 776 Property* property = expression()->AsProperty(); |
| 776 if (property == NULL) { | 777 if (property == NULL) { |
| 777 // Function call. Specialize for monomorphic calls. | 778 // Function call. Specialize for monomorphic calls. |
| 778 if (is_monomorphic_) target_ = oracle->GetCallTarget(this); | 779 if (is_monomorphic_) target_ = oracle->GetCallTarget(this); |
| 779 } else { | 780 } else if (property->key()->IsPropertyName()) { |
| 780 // Method call. Specialize for the receiver types seen at runtime. | 781 // Method call. Specialize for the receiver types seen at runtime. |
| 781 Literal* key = property->key()->AsLiteral(); | 782 Literal* key = property->key()->AsLiteral(); |
| 782 ASSERT(key != NULL && key->value()->IsString()); | 783 ASSERT(key != NULL && key->value()->IsString()); |
| 783 Handle<String> name = Handle<String>::cast(key->value()); | 784 Handle<String> name = Handle<String>::cast(key->value()); |
| 784 check_type_ = oracle->GetCallCheckType(this); | 785 check_type_ = oracle->GetCallCheckType(this); |
| 785 receiver_types_.Clear(); | 786 receiver_types_.Clear(); |
| 786 if (check_type_ == RECEIVER_MAP_CHECK) { | 787 if (check_type_ == RECEIVER_MAP_CHECK) { |
| 787 oracle->CallReceiverTypes(this, name, call_kind, &receiver_types_); | 788 oracle->CallReceiverTypes(this, name, call_kind, &receiver_types_); |
| 788 is_monomorphic_ = is_monomorphic_ && receiver_types_.length() > 0; | 789 is_monomorphic_ = is_monomorphic_ && receiver_types_.length() > 0; |
| 789 } else { | 790 } else { |
| 790 holder_ = GetPrototypeForPrimitiveCheck(check_type_, oracle->isolate()); | 791 holder_ = GetPrototypeForPrimitiveCheck(check_type_, oracle->isolate()); |
| 791 receiver_types_.Add(handle(holder_->map()), oracle->zone()); | 792 receiver_types_.Add(handle(holder_->map()), oracle->zone()); |
| 792 } | 793 } |
| 793 #ifdef ENABLE_SLOW_ASSERTS | 794 #ifdef ENABLE_SLOW_ASSERTS |
| 794 if (FLAG_enable_slow_asserts) { | 795 if (FLAG_enable_slow_asserts) { |
| 795 int length = receiver_types_.length(); | 796 int length = receiver_types_.length(); |
| 796 for (int i = 0; i < length; i++) { | 797 for (int i = 0; i < length; i++) { |
| 797 Handle<Map> map = receiver_types_.at(i); | 798 Handle<Map> map = receiver_types_.at(i); |
| 798 ASSERT(!map.is_null() && *map != NULL); | 799 ASSERT(!map.is_null() && *map != NULL); |
| 799 } | 800 } |
| 800 } | 801 } |
| 801 #endif | 802 #endif |
| 802 if (is_monomorphic_) { | 803 if (is_monomorphic_) { |
| 803 Handle<Map> map = receiver_types_.first(); | 804 Handle<Map> map = receiver_types_.first(); |
| 804 is_monomorphic_ = ComputeTarget(map, name); | 805 is_monomorphic_ = ComputeTarget(map, name); |
| 805 } | 806 } |
| 807 } else { |
| 808 if (is_monomorphic_) { |
| 809 keyed_array_call_is_holey_ = oracle->KeyedArrayCallIsHoley(this); |
| 810 } |
| 806 } | 811 } |
| 807 } | 812 } |
| 808 | 813 |
| 809 | 814 |
| 810 void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) { | 815 void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) { |
| 811 allocation_info_cell_ = oracle->GetCallNewAllocationInfoCell(this); | 816 allocation_info_cell_ = oracle->GetCallNewAllocationInfoCell(this); |
| 812 is_monomorphic_ = oracle->CallNewIsMonomorphic(this); | 817 is_monomorphic_ = oracle->CallNewIsMonomorphic(this); |
| 813 if (is_monomorphic_) { | 818 if (is_monomorphic_) { |
| 814 target_ = oracle->GetCallNewTarget(this); | 819 target_ = oracle->GetCallNewTarget(this); |
| 815 Object* value = allocation_info_cell_->value(); | 820 Object* value = allocation_info_cell_->value(); |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1326 OS::SNPrintF(buffer, "%d", Smi::cast(*value_)->value()); | 1331 OS::SNPrintF(buffer, "%d", Smi::cast(*value_)->value()); |
| 1327 str = arr; | 1332 str = arr; |
| 1328 } else { | 1333 } else { |
| 1329 str = DoubleToCString(value_->Number(), buffer); | 1334 str = DoubleToCString(value_->Number(), buffer); |
| 1330 } | 1335 } |
| 1331 return isolate_->factory()->NewStringFromAscii(CStrVector(str)); | 1336 return isolate_->factory()->NewStringFromAscii(CStrVector(str)); |
| 1332 } | 1337 } |
| 1333 | 1338 |
| 1334 | 1339 |
| 1335 } } // namespace v8::internal | 1340 } } // namespace v8::internal |
| OLD | NEW |