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

Side by Side Diff: src/hydrogen.cc

Issue 22555004: Make all load-named-fields depend on their map-check, unless explicitly ignored. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Replace ASSERT by TODO Created 7 years, 4 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
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-gvn.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 ElementsKind to_kind, 1184 ElementsKind to_kind,
1185 bool is_jsarray) { 1185 bool is_jsarray) {
1186 ASSERT(!IsFastHoleyElementsKind(from_kind) || 1186 ASSERT(!IsFastHoleyElementsKind(from_kind) ||
1187 IsFastHoleyElementsKind(to_kind)); 1187 IsFastHoleyElementsKind(to_kind));
1188 1188
1189 if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) { 1189 if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) {
1190 Add<HTrapAllocationMemento>(object); 1190 Add<HTrapAllocationMemento>(object);
1191 } 1191 }
1192 1192
1193 if (!IsSimpleMapChangeTransition(from_kind, to_kind)) { 1193 if (!IsSimpleMapChangeTransition(from_kind, to_kind)) {
1194 HInstruction* elements = AddLoadElements(object); 1194 HInstruction* elements = AddLoadElements(object, NULL);
1195 1195
1196 HInstruction* empty_fixed_array = Add<HConstant>( 1196 HInstruction* empty_fixed_array = Add<HConstant>(
1197 isolate()->factory()->empty_fixed_array()); 1197 isolate()->factory()->empty_fixed_array());
1198 1198
1199 IfBuilder if_builder(this); 1199 IfBuilder if_builder(this);
1200 1200
1201 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array); 1201 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array);
1202 1202
1203 if_builder.Then(); 1203 if_builder.Then();
1204 1204
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
1693 } 1693 }
1694 1694
1695 // Create an allocation site info if requested. 1695 // Create an allocation site info if requested.
1696 if (mode == TRACK_ALLOCATION_SITE) { 1696 if (mode == TRACK_ALLOCATION_SITE) {
1697 BuildCreateAllocationMemento(object, JSArray::kSize, allocation_site); 1697 BuildCreateAllocationMemento(object, JSArray::kSize, allocation_site);
1698 } 1698 }
1699 1699
1700 if (length > 0) { 1700 if (length > 0) {
1701 // Get hold of the elements array of the boilerplate and setup the 1701 // Get hold of the elements array of the boilerplate and setup the
1702 // elements pointer in the resulting object. 1702 // elements pointer in the resulting object.
1703 HValue* boilerplate_elements = AddLoadElements(boilerplate); 1703 HValue* boilerplate_elements = AddLoadElements(boilerplate, NULL);
1704 HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset); 1704 HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset);
1705 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 1705 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
1706 object_elements); 1706 object_elements);
1707 1707
1708 // Copy the elements array header. 1708 // Copy the elements array header.
1709 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { 1709 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
1710 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); 1710 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i);
1711 Add<HStoreNamedField>(object_elements, access, 1711 Add<HStoreNamedField>(object_elements, access,
1712 Add<HLoadNamedField>(boilerplate_elements, access)); 1712 Add<HLoadNamedField>(boilerplate_elements, access));
1713 } 1713 }
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1826 constructor_function_(constructor_function) { 1826 constructor_function_(constructor_function) {
1827 } 1827 }
1828 1828
1829 1829
1830 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() { 1830 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() {
1831 if (kind_ == GetInitialFastElementsKind()) { 1831 if (kind_ == GetInitialFastElementsKind()) {
1832 // No need for a context lookup if the kind_ matches the initial 1832 // No need for a context lookup if the kind_ matches the initial
1833 // map, because we can just load the map in that case. 1833 // map, because we can just load the map in that case.
1834 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 1834 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1835 return builder()->AddInstruction( 1835 return builder()->AddInstruction(
1836 builder()->BuildLoadNamedField(constructor_function_, access)); 1836 builder()->BuildLoadNamedField(constructor_function_, access, NULL));
1837 } 1837 }
1838 1838
1839 HInstruction* native_context = builder()->BuildGetNativeContext(); 1839 HInstruction* native_context = builder()->BuildGetNativeContext();
1840 HInstruction* index = builder()->Add<HConstant>( 1840 HInstruction* index = builder()->Add<HConstant>(
1841 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); 1841 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX));
1842 1842
1843 HInstruction* map_array = builder()->Add<HLoadKeyed>( 1843 HInstruction* map_array = builder()->Add<HLoadKeyed>(
1844 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1844 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1845 1845
1846 HInstruction* kind_index = builder()->Add<HConstant>(kind_); 1846 HInstruction* kind_index = builder()->Add<HConstant>(kind_);
1847 1847
1848 return builder()->Add<HLoadKeyed>( 1848 return builder()->Add<HLoadKeyed>(
1849 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1849 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1850 } 1850 }
1851 1851
1852 1852
1853 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { 1853 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
1854 // Find the map near the constructor function 1854 // Find the map near the constructor function
1855 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); 1855 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
1856 return builder()->AddInstruction( 1856 return builder()->AddInstruction(
1857 builder()->BuildLoadNamedField(constructor_function_, access)); 1857 builder()->BuildLoadNamedField(constructor_function_, access, NULL));
1858 } 1858 }
1859 1859
1860 1860
1861 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( 1861 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
1862 HValue* length_node) { 1862 HValue* length_node) {
1863 ASSERT(length_node != NULL); 1863 ASSERT(length_node != NULL);
1864 1864
1865 int base_size = JSArray::kSize; 1865 int base_size = JSArray::kSize;
1866 if (mode_ == TRACK_ALLOCATION_SITE) { 1866 if (mode_ == TRACK_ALLOCATION_SITE) {
1867 base_size += AllocationMemento::kSize; 1867 base_size += AllocationMemento::kSize;
(...skipping 2423 matching lines...) Expand 10 before | Expand all | Expand 10 after
4291 // TODO(mvstanton): This heuristic is only a temporary solution. In the 4291 // TODO(mvstanton): This heuristic is only a temporary solution. In the
4292 // end, we want to quit creating allocation site info after a certain number 4292 // end, we want to quit creating allocation site info after a certain number
4293 // of GCs for a call site. 4293 // of GCs for a call site.
4294 AllocationSiteMode mode = AllocationSite::GetMode( 4294 AllocationSiteMode mode = AllocationSite::GetMode(
4295 boilerplate_elements_kind); 4295 boilerplate_elements_kind);
4296 4296
4297 // Check whether to use fast or slow deep-copying for boilerplate. 4297 // Check whether to use fast or slow deep-copying for boilerplate.
4298 int data_size = 0; 4298 int data_size = 0;
4299 int pointer_size = 0; 4299 int pointer_size = 0;
4300 int max_properties = kMaxFastLiteralProperties; 4300 int max_properties = kMaxFastLiteralProperties;
4301 HCheckMaps* type_check = NULL;
4301 if (IsFastLiteral(original_boilerplate_object, 4302 if (IsFastLiteral(original_boilerplate_object,
4302 kMaxFastLiteralDepth, 4303 kMaxFastLiteralDepth,
4303 &max_properties, 4304 &max_properties,
4304 &data_size, 4305 &data_size,
4305 &pointer_size)) { 4306 &pointer_size)) {
4306 if (mode == TRACK_ALLOCATION_SITE) { 4307 if (mode == TRACK_ALLOCATION_SITE) {
4307 pointer_size += AllocationMemento::kSize; 4308 pointer_size += AllocationMemento::kSize;
4308 } 4309 }
4309 4310
4310 Handle<JSObject> boilerplate_object = DeepCopy(original_boilerplate_object); 4311 Handle<JSObject> boilerplate_object = DeepCopy(original_boilerplate_object);
(...skipping 17 matching lines...) Expand all
4328 4329
4329 Runtime::FunctionId function_id = (expr->depth() > 1) 4330 Runtime::FunctionId function_id = (expr->depth() > 1)
4330 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow; 4331 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow;
4331 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), 4332 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
4332 Runtime::FunctionForId(function_id), 4333 Runtime::FunctionForId(function_id),
4333 3); 4334 3);
4334 4335
4335 // De-opt if elements kind changed from boilerplate_elements_kind. 4336 // De-opt if elements kind changed from boilerplate_elements_kind.
4336 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(), 4337 Handle<Map> map = Handle<Map>(original_boilerplate_object->map(),
4337 isolate()); 4338 isolate());
4338 Add<HCheckMaps>(literal, map, top_info()); 4339 type_check = Add<HCheckMaps>(literal, map, top_info());
4339 } 4340 }
4340 4341
4341 // The array is expected in the bailout environment during computation 4342 // The array is expected in the bailout environment during computation
4342 // of the property values and is the value of the entire expression. 4343 // of the property values and is the value of the entire expression.
4343 Push(literal); 4344 Push(literal);
4344 // The literal index is on the stack, too. 4345 // The literal index is on the stack, too.
4345 Push(Add<HConstant>(expr->literal_index())); 4346 Push(Add<HConstant>(expr->literal_index()));
4346 4347
4347 HInstruction* elements = NULL; 4348 HInstruction* elements = NULL;
4348 4349
4349 for (int i = 0; i < length; i++) { 4350 for (int i = 0; i < length; i++) {
4350 Expression* subexpr = subexprs->at(i); 4351 Expression* subexpr = subexprs->at(i);
4351 // If the subexpression is a literal or a simple materialized literal it 4352 // If the subexpression is a literal or a simple materialized literal it
4352 // is already set in the cloned array. 4353 // is already set in the cloned array.
4353 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; 4354 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
4354 4355
4355 CHECK_ALIVE(VisitForValue(subexpr)); 4356 CHECK_ALIVE(VisitForValue(subexpr));
4356 HValue* value = Pop(); 4357 HValue* value = Pop();
4357 if (!Smi::IsValid(i)) return Bailout(kNonSmiKeyInArrayLiteral); 4358 if (!Smi::IsValid(i)) return Bailout(kNonSmiKeyInArrayLiteral);
4358 4359
4359 elements = AddLoadElements(literal); 4360 elements = AddLoadElements(literal, type_check);
4360 4361
4361 HValue* key = Add<HConstant>(i); 4362 HValue* key = Add<HConstant>(i);
4362 4363
4363 switch (boilerplate_elements_kind) { 4364 switch (boilerplate_elements_kind) {
4364 case FAST_SMI_ELEMENTS: 4365 case FAST_SMI_ELEMENTS:
4365 case FAST_HOLEY_SMI_ELEMENTS: 4366 case FAST_HOLEY_SMI_ELEMENTS:
4366 case FAST_ELEMENTS: 4367 case FAST_ELEMENTS:
4367 case FAST_HOLEY_ELEMENTS: 4368 case FAST_HOLEY_ELEMENTS:
4368 case FAST_DOUBLE_ELEMENTS: 4369 case FAST_DOUBLE_ELEMENTS:
4369 case FAST_HOLEY_DOUBLE_ELEMENTS: { 4370 case FAST_HOLEY_DOUBLE_ELEMENTS: {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4403 if (!is_store) return false; 4404 if (!is_store) return false;
4404 4405
4405 // 2nd chance: A store into a non-existent field can still be inlined if we 4406 // 2nd chance: A store into a non-existent field can still be inlined if we
4406 // have a matching transition and some room left in the object. 4407 // have a matching transition and some room left in the object.
4407 type->LookupTransition(NULL, *name, lookup); 4408 type->LookupTransition(NULL, *name, lookup);
4408 return lookup->IsTransitionToField(*type) && 4409 return lookup->IsTransitionToField(*type) &&
4409 (type->unused_property_fields() > 0); 4410 (type->unused_property_fields() > 0);
4410 } 4411 }
4411 4412
4412 4413
4413 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { 4414 HCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object,
4415 Handle<Map> map) {
4414 BuildCheckHeapObject(object); 4416 BuildCheckHeapObject(object);
4415 Add<HCheckMaps>(object, map, top_info()); 4417 return Add<HCheckMaps>(object, map, top_info());
4416 } 4418 }
4417 4419
4418 4420
4419 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( 4421 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
4420 HValue* object, 4422 HValue* object,
4421 Handle<String> name, 4423 Handle<String> name,
4422 HValue* value, 4424 HValue* value,
4423 Handle<Map> map, 4425 Handle<Map> map,
4424 LookupResult* lookup) { 4426 LookupResult* lookup) {
4425 ASSERT(lookup->IsFound()); 4427 ASSERT(lookup->IsFound());
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
4571 // In-objectness did not match. 4573 // In-objectness did not match.
4572 break; 4574 break;
4573 } 4575 }
4574 access = access.WithRepresentation( 4576 access = access.WithRepresentation(
4575 access.representation().generalize(new_access.representation())); 4577 access.representation().generalize(new_access.representation()));
4576 } 4578 }
4577 4579
4578 if (count == types->length()) { 4580 if (count == types->length()) {
4579 // Everything matched; can use monomorphic load. 4581 // Everything matched; can use monomorphic load.
4580 BuildCheckHeapObject(object); 4582 BuildCheckHeapObject(object);
4581 Add<HCheckMaps>(object, types); 4583 HCheckMaps* type_check = Add<HCheckMaps>(object, types);
4582 return BuildLoadNamedField(object, access); 4584 return BuildLoadNamedField(object, access, type_check);
4583 } 4585 }
4584 4586
4585 if (count != 0) return NULL; 4587 if (count != 0) return NULL;
4586 4588
4587 // Second chance: the property is on the prototype and all maps have the 4589 // Second chance: the property is on the prototype and all maps have the
4588 // same prototype. 4590 // same prototype.
4589 Handle<Map> map(types->at(0)); 4591 Handle<Map> map(types->at(0));
4590 if (!CanLoadPropertyFromPrototype(map, name, &lookup)) return NULL; 4592 if (!CanLoadPropertyFromPrototype(map, name, &lookup)) return NULL;
4591 4593
4592 Handle<Object> prototype(map->prototype(), isolate()); 4594 Handle<Object> prototype(map->prototype(), isolate());
4593 for (count = 1; count < types->length(); ++count) { 4595 for (count = 1; count < types->length(); ++count) {
4594 Handle<Map> test_map(types->at(count)); 4596 Handle<Map> test_map(types->at(count));
4595 if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return NULL; 4597 if (!CanLoadPropertyFromPrototype(test_map, name, &lookup)) return NULL;
4596 if (test_map->prototype() != *prototype) return NULL; 4598 if (test_map->prototype() != *prototype) return NULL;
4597 } 4599 }
4598 4600
4599 LookupInPrototypes(map, name, &lookup); 4601 LookupInPrototypes(map, name, &lookup);
4600 if (!lookup.IsField()) return NULL; 4602 if (!lookup.IsField()) return NULL;
4601 4603
4602 BuildCheckHeapObject(object); 4604 BuildCheckHeapObject(object);
4603 Add<HCheckMaps>(object, types); 4605 HCheckMaps* type_check = Add<HCheckMaps>(object, types);
4604 4606
4605 Handle<JSObject> holder(lookup.holder()); 4607 Handle<JSObject> holder(lookup.holder());
4606 Handle<Map> holder_map(holder->map()); 4608 Handle<Map> holder_map(holder->map());
4607 BuildCheckPrototypeMaps(Handle<JSObject>::cast(prototype), holder); 4609 BuildCheckPrototypeMaps(Handle<JSObject>::cast(prototype), holder);
4608 HValue* holder_value = Add<HConstant>(holder); 4610 HValue* holder_value = Add<HConstant>(holder);
4609 return BuildLoadNamedField(holder_value, 4611 return BuildLoadNamedField(holder_value,
4610 HObjectAccess::ForField(holder_map, &lookup, name)); 4612 HObjectAccess::ForField(holder_map, &lookup, name), type_check);
4611 } 4613 }
4612 4614
4613 4615
4614 // Returns true if an instance of this map can never find a property with this 4616 // Returns true if an instance of this map can never find a property with this
4615 // name in its prototype chain. This means all prototypes up to the top are 4617 // name in its prototype chain. This means all prototypes up to the top are
4616 // fast and don't have the name in them. It would be good if we could optimize 4618 // fast and don't have the name in them. It would be good if we could optimize
4617 // polymorphic loads where the property is sometimes found in the prototype 4619 // polymorphic loads where the property is sometimes found in the prototype
4618 // chain. 4620 // chain.
4619 static bool PrototypeChainCanNeverResolve( 4621 static bool PrototypeChainCanNeverResolve(
4620 Handle<Map> map, Handle<String> name) { 4622 Handle<Map> map, Handle<String> name) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
4675 HBasicBlock* if_false = graph()->CreateBasicBlock(); 4677 HBasicBlock* if_false = graph()->CreateBasicBlock();
4676 HCompareMap* compare = 4678 HCompareMap* compare =
4677 new(zone()) HCompareMap(object, map, if_true, if_false); 4679 new(zone()) HCompareMap(object, map, if_true, if_false);
4678 current_block()->Finish(compare); 4680 current_block()->Finish(compare);
4679 4681
4680 set_current_block(if_true); 4682 set_current_block(if_true);
4681 4683
4682 // TODO(verwaest): Merge logic with BuildLoadNamedMonomorphic. 4684 // TODO(verwaest): Merge logic with BuildLoadNamedMonomorphic.
4683 if (lookup.IsField()) { 4685 if (lookup.IsField()) {
4684 HObjectAccess access = HObjectAccess::ForField(map, &lookup, name); 4686 HObjectAccess access = HObjectAccess::ForField(map, &lookup, name);
4685 HLoadNamedField* load = BuildLoadNamedField(object, access); 4687 HLoadNamedField* load = BuildLoadNamedField(object, access, compare);
4686 load->set_position(expr->position()); 4688 load->set_position(expr->position());
4687 AddInstruction(load); 4689 AddInstruction(load);
4688 if (!ast_context()->IsEffect()) Push(load); 4690 if (!ast_context()->IsEffect()) Push(load);
4689 } else if (lookup.IsConstant()) { 4691 } else if (lookup.IsConstant()) {
4690 Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate()); 4692 Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate());
4691 HConstant* hconstant = Add<HConstant>(constant); 4693 HConstant* hconstant = Add<HConstant>(constant);
4692 if (!ast_context()->IsEffect()) Push(hconstant); 4694 if (!ast_context()->IsEffect()) Push(hconstant);
4693 } else { 4695 } else {
4694 ASSERT(!lookup.IsFound()); 4696 ASSERT(!lookup.IsFound());
4695 if (map->prototype()->IsJSObject()) { 4697 if (map->prototype()->IsJSObject()) {
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after
5412 HValue* object, 5414 HValue* object,
5413 Handle<String> name, 5415 Handle<String> name,
5414 Property* expr, 5416 Property* expr,
5415 Handle<Map> map) { 5417 Handle<Map> map) {
5416 // Handle a load from a known field. 5418 // Handle a load from a known field.
5417 ASSERT(!map->is_dictionary_map()); 5419 ASSERT(!map->is_dictionary_map());
5418 5420
5419 // Handle access to various length properties 5421 // Handle access to various length properties
5420 if (name->Equals(isolate()->heap()->length_string())) { 5422 if (name->Equals(isolate()->heap()->length_string())) {
5421 if (map->instance_type() == JS_ARRAY_TYPE) { 5423 if (map->instance_type() == JS_ARRAY_TYPE) {
5422 AddCheckMap(object, map); 5424 HCheckMaps* type_check = AddCheckMap(object, map);
5423 return New<HLoadNamedField>(object, 5425 return New<HLoadNamedField>(object,
5424 HObjectAccess::ForArrayLength(map->elements_kind())); 5426 HObjectAccess::ForArrayLength(map->elements_kind()), type_check);
5425 } 5427 }
5426 } 5428 }
5427 5429
5428 LookupResult lookup(isolate()); 5430 LookupResult lookup(isolate());
5429 map->LookupDescriptor(NULL, *name, &lookup); 5431 map->LookupDescriptor(NULL, *name, &lookup);
5430 if (lookup.IsField()) { 5432 if (lookup.IsField()) {
5431 AddCheckMap(object, map); 5433 HCheckMaps* type_check = AddCheckMap(object, map);
5432 return BuildLoadNamedField(object, 5434 return BuildLoadNamedField(object,
5433 HObjectAccess::ForField(map, &lookup, name)); 5435 HObjectAccess::ForField(map, &lookup, name), type_check);
5434 } 5436 }
5435 5437
5436 // Handle a load of a constant known function. 5438 // Handle a load of a constant known function.
5437 if (lookup.IsConstant()) { 5439 if (lookup.IsConstant()) {
5438 AddCheckMap(object, map); 5440 AddCheckMap(object, map);
5439 Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate()); 5441 Handle<Object> constant(lookup.GetConstantFromMap(*map), isolate());
5440 return New<HConstant>(constant); 5442 return New<HConstant>(constant);
5441 } 5443 }
5442 5444
5443 // Handle a load from a known field somewhere in the prototype chain. 5445 // Handle a load from a known field somewhere in the prototype chain.
5444 LookupInPrototypes(map, name, &lookup); 5446 LookupInPrototypes(map, name, &lookup);
5445 if (lookup.IsField()) { 5447 if (lookup.IsField()) {
5446 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 5448 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
5447 Handle<JSObject> holder(lookup.holder()); 5449 Handle<JSObject> holder(lookup.holder());
5448 Handle<Map> holder_map(holder->map()); 5450 Handle<Map> holder_map(holder->map());
5449 AddCheckMap(object, map); 5451 HCheckMaps* type_check = AddCheckMap(object, map);
5450 BuildCheckPrototypeMaps(prototype, holder); 5452 BuildCheckPrototypeMaps(prototype, holder);
5451 HValue* holder_value = Add<HConstant>(holder); 5453 HValue* holder_value = Add<HConstant>(holder);
5452 return BuildLoadNamedField(holder_value, 5454 return BuildLoadNamedField(holder_value,
5453 HObjectAccess::ForField(holder_map, &lookup, name)); 5455 HObjectAccess::ForField(holder_map, &lookup, name), type_check);
5454 } 5456 }
5455 5457
5456 // Handle a load of a constant function somewhere in the prototype chain. 5458 // Handle a load of a constant function somewhere in the prototype chain.
5457 if (lookup.IsConstant()) { 5459 if (lookup.IsConstant()) {
5458 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 5460 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
5459 Handle<JSObject> holder(lookup.holder()); 5461 Handle<JSObject> holder(lookup.holder());
5460 Handle<Map> holder_map(holder->map()); 5462 Handle<Map> holder_map(holder->map());
5461 AddCheckMap(object, map); 5463 AddCheckMap(object, map);
5462 BuildCheckPrototypeMaps(prototype, holder); 5464 BuildCheckPrototypeMaps(prototype, holder);
5463 Handle<Object> constant(lookup.GetConstantFromMap(*holder_map), isolate()); 5465 Handle<Object> constant(lookup.GetConstantFromMap(*holder_map), isolate());
(...skipping 4363 matching lines...) Expand 10 before | Expand all | Expand 10 after
9827 if (ShouldProduceTraceOutput()) { 9829 if (ShouldProduceTraceOutput()) {
9828 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9830 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9829 } 9831 }
9830 9832
9831 #ifdef DEBUG 9833 #ifdef DEBUG
9832 graph_->Verify(false); // No full verify. 9834 graph_->Verify(false); // No full verify.
9833 #endif 9835 #endif
9834 } 9836 }
9835 9837
9836 } } // namespace v8::internal 9838 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-gvn.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698