| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 1170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1181 ElementsKind to_kind, | 1181 ElementsKind to_kind, |
| 1182 bool is_jsarray) { | 1182 bool is_jsarray) { |
| 1183 ASSERT(!IsFastHoleyElementsKind(from_kind) || | 1183 ASSERT(!IsFastHoleyElementsKind(from_kind) || |
| 1184 IsFastHoleyElementsKind(to_kind)); | 1184 IsFastHoleyElementsKind(to_kind)); |
| 1185 | 1185 |
| 1186 if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) { | 1186 if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) { |
| 1187 Add<HTrapAllocationMemento>(object); | 1187 Add<HTrapAllocationMemento>(object); |
| 1188 } | 1188 } |
| 1189 | 1189 |
| 1190 if (!IsSimpleMapChangeTransition(from_kind, to_kind)) { | 1190 if (!IsSimpleMapChangeTransition(from_kind, to_kind)) { |
| 1191 HInstruction* elements = AddLoadElements(object); | 1191 HInstruction* elements = AddLoadElements(object, NULL); |
| 1192 | 1192 |
| 1193 HInstruction* empty_fixed_array = Add<HConstant>( | 1193 HInstruction* empty_fixed_array = Add<HConstant>( |
| 1194 isolate()->factory()->empty_fixed_array()); | 1194 isolate()->factory()->empty_fixed_array()); |
| 1195 | 1195 |
| 1196 IfBuilder if_builder(this); | 1196 IfBuilder if_builder(this); |
| 1197 | 1197 |
| 1198 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array); | 1198 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array); |
| 1199 | 1199 |
| 1200 if_builder.Then(); | 1200 if_builder.Then(); |
| 1201 | 1201 |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1690 } | 1690 } |
| 1691 | 1691 |
| 1692 // Create an allocation site info if requested. | 1692 // Create an allocation site info if requested. |
| 1693 if (mode == TRACK_ALLOCATION_SITE) { | 1693 if (mode == TRACK_ALLOCATION_SITE) { |
| 1694 BuildCreateAllocationMemento(object, JSArray::kSize, allocation_site); | 1694 BuildCreateAllocationMemento(object, JSArray::kSize, allocation_site); |
| 1695 } | 1695 } |
| 1696 | 1696 |
| 1697 if (length > 0) { | 1697 if (length > 0) { |
| 1698 // Get hold of the elements array of the boilerplate and setup the | 1698 // Get hold of the elements array of the boilerplate and setup the |
| 1699 // elements pointer in the resulting object. | 1699 // elements pointer in the resulting object. |
| 1700 HValue* boilerplate_elements = AddLoadElements(boilerplate); | 1700 HValue* boilerplate_elements = AddLoadElements(boilerplate, NULL); |
| 1701 HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset); | 1701 HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset); |
| 1702 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), | 1702 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), |
| 1703 object_elements); | 1703 object_elements); |
| 1704 | 1704 |
| 1705 // Copy the elements array header. | 1705 // Copy the elements array header. |
| 1706 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { | 1706 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { |
| 1707 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); | 1707 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); |
| 1708 Add<HStoreNamedField>(object_elements, access, | 1708 Add<HStoreNamedField>(object_elements, access, |
| 1709 Add<HLoadNamedField>(boilerplate_elements, access)); | 1709 Add<HLoadNamedField>(boilerplate_elements, access)); |
| 1710 } | 1710 } |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1855 constructor_function_(constructor_function) { | 1855 constructor_function_(constructor_function) { |
| 1856 } | 1856 } |
| 1857 | 1857 |
| 1858 | 1858 |
| 1859 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() { | 1859 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() { |
| 1860 if (kind_ == GetInitialFastElementsKind()) { | 1860 if (kind_ == GetInitialFastElementsKind()) { |
| 1861 // No need for a context lookup if the kind_ matches the initial | 1861 // No need for a context lookup if the kind_ matches the initial |
| 1862 // map, because we can just load the map in that case. | 1862 // map, because we can just load the map in that case. |
| 1863 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 1863 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
| 1864 return builder()->AddInstruction( | 1864 return builder()->AddInstruction( |
| 1865 builder()->BuildLoadNamedField(constructor_function_, access)); | 1865 builder()->BuildLoadNamedField(constructor_function_, access, NULL)); |
| 1866 } | 1866 } |
| 1867 | 1867 |
| 1868 HInstruction* native_context = builder()->BuildGetNativeContext(); | 1868 HInstruction* native_context = builder()->BuildGetNativeContext(); |
| 1869 HInstruction* index = builder()->Add<HConstant>( | 1869 HInstruction* index = builder()->Add<HConstant>( |
| 1870 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); | 1870 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); |
| 1871 | 1871 |
| 1872 HInstruction* map_array = builder()->Add<HLoadKeyed>( | 1872 HInstruction* map_array = builder()->Add<HLoadKeyed>( |
| 1873 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 1873 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
| 1874 | 1874 |
| 1875 HInstruction* kind_index = builder()->Add<HConstant>(kind_); | 1875 HInstruction* kind_index = builder()->Add<HConstant>(kind_); |
| 1876 | 1876 |
| 1877 return builder()->Add<HLoadKeyed>( | 1877 return builder()->Add<HLoadKeyed>( |
| 1878 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 1878 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
| 1879 } | 1879 } |
| 1880 | 1880 |
| 1881 | 1881 |
| 1882 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { | 1882 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { |
| 1883 // Find the map near the constructor function | 1883 // Find the map near the constructor function |
| 1884 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 1884 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
| 1885 return builder()->AddInstruction( | 1885 return builder()->AddInstruction( |
| 1886 builder()->BuildLoadNamedField(constructor_function_, access)); | 1886 builder()->BuildLoadNamedField(constructor_function_, access, NULL)); |
| 1887 } | 1887 } |
| 1888 | 1888 |
| 1889 | 1889 |
| 1890 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( | 1890 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( |
| 1891 HValue* length_node) { | 1891 HValue* length_node) { |
| 1892 ASSERT(length_node != NULL); | 1892 ASSERT(length_node != NULL); |
| 1893 | 1893 |
| 1894 int base_size = JSArray::kSize; | 1894 int base_size = JSArray::kSize; |
| 1895 if (mode_ == TRACK_ALLOCATION_SITE) { | 1895 if (mode_ == TRACK_ALLOCATION_SITE) { |
| 1896 base_size += AllocationMemento::kSize; | 1896 base_size += AllocationMemento::kSize; |
| (...skipping 2471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4368 // TODO(mvstanton): This heuristic is only a temporary solution. In the | 4368 // TODO(mvstanton): This heuristic is only a temporary solution. In the |
| 4369 // end, we want to quit creating allocation site info after a certain number | 4369 // end, we want to quit creating allocation site info after a certain number |
| 4370 // of GCs for a call site. | 4370 // of GCs for a call site. |
| 4371 AllocationSiteMode mode = AllocationSite::GetMode( | 4371 AllocationSiteMode mode = AllocationSite::GetMode( |
| 4372 boilerplate_elements_kind); | 4372 boilerplate_elements_kind); |
| 4373 | 4373 |
| 4374 // Check whether to use fast or slow deep-copying for boilerplate. | 4374 // Check whether to use fast or slow deep-copying for boilerplate. |
| 4375 int data_size = 0; | 4375 int data_size = 0; |
| 4376 int pointer_size = 0; | 4376 int pointer_size = 0; |
| 4377 int max_properties = kMaxFastLiteralProperties; | 4377 int max_properties = kMaxFastLiteralProperties; |
| 4378 HCheckMaps* type_check = NULL; |
| 4378 if (IsFastLiteral(original_boilerplate_object, | 4379 if (IsFastLiteral(original_boilerplate_object, |
| 4379 kMaxFastLiteralDepth, | 4380 kMaxFastLiteralDepth, |
| 4380 &max_properties, | 4381 &max_properties, |
| 4381 &data_size, | 4382 &data_size, |
| 4382 &pointer_size)) { | 4383 &pointer_size)) { |
| 4383 if (mode == TRACK_ALLOCATION_SITE) { | 4384 if (mode == TRACK_ALLOCATION_SITE) { |
| 4384 pointer_size += AllocationMemento::kSize; | 4385 pointer_size += AllocationMemento::kSize; |
| 4385 } | 4386 } |
| 4386 | 4387 |
| 4387 Handle<JSObject> boilerplate_object = DeepCopy(original_boilerplate_object); | 4388 Handle<JSObject> boilerplate_object = DeepCopy(original_boilerplate_object); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 4405 | 4406 |
| 4406 Runtime::FunctionId function_id = (expr->depth() > 1) | 4407 Runtime::FunctionId function_id = (expr->depth() > 1) |
| 4407 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; | 4408 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; |
| 4408 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 4409 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), |
| 4409 Runtime::FunctionForId(function_id), | 4410 Runtime::FunctionForId(function_id), |
| 4410 3); | 4411 3); |
| 4411 | 4412 |
| 4412 // De-opt if elements kind changed from boilerplate_elements_kind. | 4413 // De-opt if elements kind changed from boilerplate_elements_kind. |
| 4413 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(), | 4414 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(), |
| 4414 isolate()); | 4415 isolate()); |
| 4415 Add<HCheckMaps>(literal, map, top_info()); | 4416 type_check = Add<HCheckMaps>(literal, map, top_info()); |
| 4416 } | 4417 } |
| 4417 | 4418 |
| 4418 // The array is expected in the bailout environment during computation | 4419 // The array is expected in the bailout environment during computation |
| 4419 // of the property values and is the value of the entire expression. | 4420 // of the property values and is the value of the entire expression. |
| 4420 Push(literal); | 4421 Push(literal); |
| 4421 // The literal index is on the stack, too. | 4422 // The literal index is on the stack, too. |
| 4422 Push(Add<HConstant>(expr->literal_index())); | 4423 Push(Add<HConstant>(expr->literal_index())); |
| 4423 | 4424 |
| 4424 HInstruction* elements = NULL; | 4425 HInstruction* elements = NULL; |
| 4425 | 4426 |
| 4426 for (int i = 0; i < length; i++) { | 4427 for (int i = 0; i < length; i++) { |
| 4427 Expression* subexpr = subexprs->at(i); | 4428 Expression* subexpr = subexprs->at(i); |
| 4428 // If the subexpression is a literal or a simple materialized literal it | 4429 // If the subexpression is a literal or a simple materialized literal it |
| 4429 // is already set in the cloned array. | 4430 // is already set in the cloned array. |
| 4430 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 4431 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
| 4431 | 4432 |
| 4432 CHECK_ALIVE(VisitForValue(subexpr)); | 4433 CHECK_ALIVE(VisitForValue(subexpr)); |
| 4433 HValue* value = Pop(); | 4434 HValue* value = Pop(); |
| 4434 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); | 4435 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); |
| 4435 | 4436 |
| 4436 elements = AddLoadElements(literal); | 4437 elements = AddLoadElements(literal, type_check); |
| 4437 | 4438 |
| 4438 HValue* key = Add<HConstant>(i); | 4439 HValue* key = Add<HConstant>(i); |
| 4439 | 4440 |
| 4440 switch (boilerplate_elements_kind) { | 4441 switch (boilerplate_elements_kind) { |
| 4441 case FAST_SMI_ELEMENTS: | 4442 case FAST_SMI_ELEMENTS: |
| 4442 case FAST_HOLEY_SMI_ELEMENTS: | 4443 case FAST_HOLEY_SMI_ELEMENTS: |
| 4443 case FAST_ELEMENTS: | 4444 case FAST_ELEMENTS: |
| 4444 case FAST_HOLEY_ELEMENTS: | 4445 case FAST_HOLEY_ELEMENTS: |
| 4445 case FAST_DOUBLE_ELEMENTS: | 4446 case FAST_DOUBLE_ELEMENTS: |
| 4446 case FAST_HOLEY_DOUBLE_ELEMENTS: { | 4447 case FAST_HOLEY_DOUBLE_ELEMENTS: { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4480 if (!is_store) return false; | 4481 if (!is_store) return false; |
| 4481 | 4482 |
| 4482 // 2nd chance: A store into a non-existent field can still be inlined if we | 4483 // 2nd chance: A store into a non-existent field can still be inlined if we |
| 4483 // have a matching transition and some room left in the object. | 4484 // have a matching transition and some room left in the object. |
| 4484 type->LookupTransition(NULL, *name, lookup); | 4485 type->LookupTransition(NULL, *name, lookup); |
| 4485 return lookup->IsTransitionToField(*type) && | 4486 return lookup->IsTransitionToField(*type) && |
| 4486 (type->unused_property_fields() > 0); | 4487 (type->unused_property_fields() > 0); |
| 4487 } | 4488 } |
| 4488 | 4489 |
| 4489 | 4490 |
| 4490 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { | 4491 HCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object, |
| 4492 Handle<Map> map) { |
| 4491 BuildCheckHeapObject(object); | 4493 BuildCheckHeapObject(object); |
| 4492 Add<HCheckMaps>(object, map, top_info()); | 4494 return Add<HCheckMaps>(object, map, top_info()); |
| 4493 } | 4495 } |
| 4494 | 4496 |
| 4495 | 4497 |
| 4496 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( | 4498 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( |
| 4497 HValue* object, | 4499 HValue* object, |
| 4498 Handle<String> name, | 4500 Handle<String> name, |
| 4499 HValue* value, | 4501 HValue* value, |
| 4500 Handle<Map> map, | 4502 Handle<Map> map, |
| 4501 LookupResult* lookup) { | 4503 LookupResult* lookup) { |
| 4502 ASSERT(lookup->IsFound()); | 4504 ASSERT(lookup->IsFound()); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4647 // In-objectness did not match. | 4649 // In-objectness did not match. |
| 4648 break; | 4650 break; |
| 4649 } | 4651 } |
| 4650 access = access.WithRepresentation( | 4652 access = access.WithRepresentation( |
| 4651 access.representation().generalize(new_access.representation())); | 4653 access.representation().generalize(new_access.representation())); |
| 4652 } | 4654 } |
| 4653 | 4655 |
| 4654 if (count == types->length()) { | 4656 if (count == types->length()) { |
| 4655 // Everything matched; can use monomorphic load. | 4657 // Everything matched; can use monomorphic load. |
| 4656 BuildCheckHeapObject(object); | 4658 BuildCheckHeapObject(object); |
| 4657 Add<HCheckMaps>(object, types); | 4659 HCheckMaps* type_check = Add<HCheckMaps>(object, types); |
| 4658 return BuildLoadNamedField(object, access); | 4660 return BuildLoadNamedField(object, access, type_check); |
| 4659 } | 4661 } |
| 4660 | 4662 |
| 4661 if (count != 0) return NULL; | 4663 if (count != 0) return NULL; |
| 4662 | 4664 |
| 4663 // Second chance: the property is on the prototype and all maps have the | 4665 // Second chance: the property is on the prototype and all maps have the |
| 4664 // same prototype. | 4666 // same prototype. |
| 4665 Handle<Map> map(types->at(0)); | 4667 Handle<Map> map(types->at(0)); |
| 4666 if (!CanLoadPropertyFromPrototype(map, name, &lookup)) return NULL; | 4668 if (!CanLoadPropertyFromPrototype(map, name, &lookup)) return NULL; |
| 4667 | 4669 |
| 4668 Handle<Object> prototype(map->prototype(), isolate()); | 4670 Handle<Object> prototype(map->prototype(), isolate()); |
| 4669 for (count = 1; count < types->length(); ++count) { | 4671 for (count = 1; count < types->length(); ++count) { |
| 4670 Handle<Map> test_map(types->at(count)); | 4672 Handle<Map> test_map(types->at(count)); |
| 4671 if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return NULL; | 4673 if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return NULL; |
| 4672 if (test_map->prototype() != *prototype) return NULL; | 4674 if (test_map->prototype() != *prototype) return NULL; |
| 4673 } | 4675 } |
| 4674 | 4676 |
| 4675 LookupInPrototypes(map, name, &lookup); | 4677 LookupInPrototypes(map, name, &lookup); |
| 4676 if (!lookup.IsField()) return NULL; | 4678 if (!lookup.IsField()) return NULL; |
| 4677 | 4679 |
| 4678 BuildCheckHeapObject(object); | 4680 BuildCheckHeapObject(object); |
| 4679 Add<HCheckMaps>(object, types); | 4681 HCheckMaps* type_check = Add<HCheckMaps>(object, types); |
| 4680 | 4682 |
| 4681 Handle<JSObject> holder(lookup.holder()); | 4683 Handle<JSObject> holder(lookup.holder()); |
| 4682 Handle<Map> holder_map(holder->map()); | 4684 Handle<Map> holder_map(holder->map()); |
| 4683 Add<HCheckPrototypeMaps>( | 4685 Add<HCheckPrototypeMaps>( |
| 4684 Handle<JSObject>::cast(prototype), holder, top_info()); | 4686 Handle<JSObject>::cast(prototype), holder, top_info()); |
| 4685 HValue* holder_value = Add<HConstant>(holder); | 4687 HValue* holder_value = Add<HConstant>(holder); |
| 4686 return BuildLoadNamedField(holder_value, | 4688 return BuildLoadNamedField(holder_value, |
| 4687 HObjectAccess::ForField(holder_map, &lookup, name)); | 4689 HObjectAccess::ForField(holder_map, &lookup, name), type_check); |
| 4688 } | 4690 } |
| 4689 | 4691 |
| 4690 | 4692 |
| 4691 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( | 4693 void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
| 4692 Property* expr, | 4694 Property* expr, |
| 4693 HValue* object, | 4695 HValue* object, |
| 4694 SmallMapList* types, | 4696 SmallMapList* types, |
| 4695 Handle<String> name) { | 4697 Handle<String> name) { |
| 4696 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( | 4698 HInstruction* instr = TryLoadPolymorphicAsMonomorphic( |
| 4697 expr, object, types, name); | 4699 expr, object, types, name); |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5381 HValue* object, | 5383 HValue* object, |
| 5382 Handle<String> name, | 5384 Handle<String> name, |
| 5383 Property* expr, | 5385 Property* expr, |
| 5384 Handle<Map> map) { | 5386 Handle<Map> map) { |
| 5385 // Handle a load from a known field. | 5387 // Handle a load from a known field. |
| 5386 ASSERT(!map->is_dictionary_map()); | 5388 ASSERT(!map->is_dictionary_map()); |
| 5387 | 5389 |
| 5388 // Handle access to various length properties | 5390 // Handle access to various length properties |
| 5389 if (name->Equals(isolate()->heap()->length_string())) { | 5391 if (name->Equals(isolate()->heap()->length_string())) { |
| 5390 if (map->instance_type() == JS_ARRAY_TYPE) { | 5392 if (map->instance_type() == JS_ARRAY_TYPE) { |
| 5391 AddCheckMap(object, map); | 5393 HCheckMaps* type_check = AddCheckMap(object, map); |
| 5392 return New<HLoadNamedField>(object, | 5394 return New<HLoadNamedField>(object, |
| 5393 HObjectAccess::ForArrayLength(map->elements_kind())); | 5395 HObjectAccess::ForArrayLength(map->elements_kind()), type_check); |
| 5394 } | 5396 } |
| 5395 } | 5397 } |
| 5396 | 5398 |
| 5397 LookupResult lookup(isolate()); | 5399 LookupResult lookup(isolate()); |
| 5398 map->LookupDescriptor(NULL, *name, &lookup); | 5400 map->LookupDescriptor(NULL, *name, &lookup); |
| 5399 if (lookup.IsField()) { | 5401 if (lookup.IsField()) { |
| 5400 AddCheckMap(object, map); | 5402 HCheckMaps* type_check = AddCheckMap(object, map); |
| 5401 return BuildLoadNamedField(object, | 5403 return BuildLoadNamedField(object, |
| 5402 HObjectAccess::ForField(map, &lookup, name)); | 5404 HObjectAccess::ForField(map, &lookup, name), type_check); |
| 5403 } | 5405 } |
| 5404 | 5406 |
| 5405 // Handle a load of a constant known function. | 5407 // Handle a load of a constant known function. |
| 5406 if (lookup.IsConstant()) { | 5408 if (lookup.IsConstant()) { |
| 5407 AddCheckMap(object, map); | 5409 AddCheckMap(object, map); |
| 5408 Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate()); | 5410 Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate()); |
| 5409 return New<HConstant>(constant); | 5411 return New<HConstant>(constant); |
| 5410 } | 5412 } |
| 5411 | 5413 |
| 5412 // Handle a load from a known field somewhere in the prototype chain. | 5414 // Handle a load from a known field somewhere in the prototype chain. |
| 5413 LookupInPrototypes(map, name, &lookup); | 5415 LookupInPrototypes(map, name, &lookup); |
| 5414 if (lookup.IsField()) { | 5416 if (lookup.IsField()) { |
| 5415 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 5417 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
| 5416 Handle<JSObject> holder(lookup.holder()); | 5418 Handle<JSObject> holder(lookup.holder()); |
| 5417 Handle<Map> holder_map(holder->map()); | 5419 Handle<Map> holder_map(holder->map()); |
| 5418 AddCheckMap(object, map); | 5420 HCheckMaps* type_check = AddCheckMap(object, map); |
| 5419 Add<HCheckPrototypeMaps>(prototype, holder, top_info()); | 5421 Add<HCheckPrototypeMaps>(prototype, holder, top_info()); |
| 5420 HValue* holder_value = Add<HConstant>(holder); | 5422 HValue* holder_value = Add<HConstant>(holder); |
| 5421 return BuildLoadNamedField(holder_value, | 5423 return BuildLoadNamedField(holder_value, |
| 5422 HObjectAccess::ForField(holder_map, &lookup, name)); | 5424 HObjectAccess::ForField(holder_map, &lookup, name), type_check); |
| 5423 } | 5425 } |
| 5424 | 5426 |
| 5425 // Handle a load of a constant function somewhere in the prototype chain. | 5427 // Handle a load of a constant function somewhere in the prototype chain. |
| 5426 if (lookup.IsConstant()) { | 5428 if (lookup.IsConstant()) { |
| 5427 Handle<JSObject> prototype(JSObject::cast(map->prototype())); | 5429 Handle<JSObject> prototype(JSObject::cast(map->prototype())); |
| 5428 Handle<JSObject> holder(lookup.holder()); | 5430 Handle<JSObject> holder(lookup.holder()); |
| 5429 Handle<Map> holder_map(holder->map()); | 5431 Handle<Map> holder_map(holder->map()); |
| 5430 AddCheckMap(object, map); | 5432 AddCheckMap(object, map); |
| 5431 Add<HCheckPrototypeMaps>(prototype, holder, top_info()); | 5433 Add<HCheckPrototypeMaps>(prototype, holder, top_info()); |
| 5432 Handle<Object> constant(lookup.GetConstantFromMap(*holder_map), isolate()); | 5434 Handle<Object> constant(lookup.GetConstantFromMap(*holder_map), isolate()); |
| (...skipping 4351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9784 if (ShouldProduceTraceOutput()) { | 9786 if (ShouldProduceTraceOutput()) { |
| 9785 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9787 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 9786 } | 9788 } |
| 9787 | 9789 |
| 9788 #ifdef DEBUG | 9790 #ifdef DEBUG |
| 9789 graph_->Verify(false); // No full verify. | 9791 graph_->Verify(false); // No full verify. |
| 9790 #endif | 9792 #endif |
| 9791 } | 9793 } |
| 9792 | 9794 |
| 9793 } } // namespace v8::internal | 9795 } } // namespace v8::internal |
| OLD | NEW |