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 |