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 4425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4436 | 4436 |
4437 | 4437 |
4438 HCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object, | 4438 HCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object, |
4439 Handle<Map> map) { | 4439 Handle<Map> map) { |
4440 BuildCheckHeapObject(object); | 4440 BuildCheckHeapObject(object); |
4441 return Add<HCheckMaps>(object, map, top_info()); | 4441 return Add<HCheckMaps>(object, map, top_info()); |
4442 } | 4442 } |
4443 | 4443 |
4444 | 4444 |
4445 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( | 4445 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( |
4446 HValue* object, | 4446 HValue* checked_object, |
4447 Handle<String> name, | 4447 Handle<String> name, |
4448 HValue* value, | 4448 HValue* value, |
4449 Handle<Map> map, | 4449 Handle<Map> map, |
4450 LookupResult* lookup) { | 4450 LookupResult* lookup) { |
4451 ASSERT(lookup->IsFound()); | 4451 ASSERT(lookup->IsFound()); |
4452 // If the property does not exist yet, we have to check that it wasn't made | 4452 // If the property does not exist yet, we have to check that it wasn't made |
4453 // readonly or turned into a setter by some meanwhile modifications on the | 4453 // readonly or turned into a setter by some meanwhile modifications on the |
4454 // prototype chain. | 4454 // prototype chain. |
4455 if (!lookup->IsProperty() && map->prototype()->IsJSReceiver()) { | 4455 if (!lookup->IsProperty() && map->prototype()->IsJSReceiver()) { |
4456 Object* proto = map->prototype(); | 4456 Object* proto = map->prototype(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4488 if (transition_to_field) { | 4488 if (transition_to_field) { |
4489 // The store requires a mutable HeapNumber to be allocated. | 4489 // The store requires a mutable HeapNumber to be allocated. |
4490 NoObservableSideEffectsScope no_side_effects(this); | 4490 NoObservableSideEffectsScope no_side_effects(this); |
4491 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); | 4491 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); |
4492 HInstruction* heap_number = Add<HAllocate>(heap_number_size, | 4492 HInstruction* heap_number = Add<HAllocate>(heap_number_size, |
4493 HType::HeapNumber(), isolate()->heap()->GetPretenureMode(), | 4493 HType::HeapNumber(), isolate()->heap()->GetPretenureMode(), |
4494 HEAP_NUMBER_TYPE); | 4494 HEAP_NUMBER_TYPE); |
4495 AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map()); | 4495 AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map()); |
4496 Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), | 4496 Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), |
4497 value); | 4497 value); |
4498 instr = New<HStoreNamedField>(object, heap_number_access, | 4498 instr = New<HStoreNamedField>(checked_object, |
4499 heap_number); | 4499 heap_number_access, |
| 4500 heap_number); |
4500 } else { | 4501 } else { |
4501 // Already holds a HeapNumber; load the box and write its value field. | 4502 // Already holds a HeapNumber; load the box and write its value field. |
4502 HInstruction* heap_number = Add<HLoadNamedField>(object, | 4503 HInstruction* heap_number = Add<HLoadNamedField>(checked_object, |
4503 heap_number_access); | 4504 heap_number_access); |
4504 heap_number->set_type(HType::HeapNumber()); | 4505 heap_number->set_type(HType::HeapNumber()); |
4505 instr = New<HStoreNamedField>(heap_number, | 4506 instr = New<HStoreNamedField>(heap_number, |
4506 HObjectAccess::ForHeapNumberValue(), | 4507 HObjectAccess::ForHeapNumberValue(), |
4507 value); | 4508 value); |
4508 } | 4509 } |
4509 } else { | 4510 } else { |
4510 // This is a normal store. | 4511 // This is a normal store. |
4511 instr = New<HStoreNamedField>(object, field_access, value); | 4512 instr = New<HStoreNamedField>(checked_object, field_access, value); |
4512 } | 4513 } |
4513 | 4514 |
4514 if (transition_to_field) { | 4515 if (transition_to_field) { |
4515 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); | 4516 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); |
4516 HConstant* transition_constant = Add<HConstant>(transition); | 4517 HConstant* transition_constant = Add<HConstant>(transition); |
4517 instr->SetTransition(transition_constant, top_info()); | 4518 instr->SetTransition(transition_constant, top_info()); |
4518 // TODO(fschneider): Record the new map type of the object in the IR to | 4519 // TODO(fschneider): Record the new map type of the object in the IR to |
4519 // enable elimination of redundant checks after the transition store. | 4520 // enable elimination of redundant checks after the transition store. |
4520 instr->SetGVNFlag(kChangesMaps); | 4521 instr->SetGVNFlag(kChangesMaps); |
4521 } | 4522 } |
(...skipping 16 matching lines...) Expand all Loading... |
4538 | 4539 |
4539 | 4540 |
4540 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic( | 4541 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic( |
4541 HValue* object, | 4542 HValue* object, |
4542 Handle<String> name, | 4543 Handle<String> name, |
4543 HValue* value, | 4544 HValue* value, |
4544 Handle<Map> map) { | 4545 Handle<Map> map) { |
4545 // Handle a store to a known field. | 4546 // Handle a store to a known field. |
4546 LookupResult lookup(isolate()); | 4547 LookupResult lookup(isolate()); |
4547 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 4548 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
4548 AddCheckMap(object, map); | 4549 HCheckMaps* checked_object = AddCheckMap(object, map); |
4549 return BuildStoreNamedField(object, name, value, map, &lookup); | 4550 return BuildStoreNamedField(checked_object, name, value, map, &lookup); |
4550 } | 4551 } |
4551 | 4552 |
4552 // No luck, do a generic store. | 4553 // No luck, do a generic store. |
4553 return BuildStoreNamedGeneric(object, name, value); | 4554 return BuildStoreNamedGeneric(object, name, value); |
4554 } | 4555 } |
4555 | 4556 |
4556 | 4557 |
4557 static bool CanLoadPropertyFromPrototype(Handle<Map> map, | 4558 static bool CanLoadPropertyFromPrototype(Handle<Map> map, |
4558 Handle<Name> name, | 4559 Handle<Name> name, |
4559 LookupResult* lookup) { | 4560 LookupResult* lookup) { |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4801 } else if (access.IsInobject() != new_access.IsInobject()) { | 4802 } else if (access.IsInobject() != new_access.IsInobject()) { |
4802 // In-objectness did not match. | 4803 // In-objectness did not match. |
4803 break; | 4804 break; |
4804 } | 4805 } |
4805 } | 4806 } |
4806 | 4807 |
4807 if (count != types->length()) return false; | 4808 if (count != types->length()) return false; |
4808 | 4809 |
4809 // Everything matched; can use monomorphic store. | 4810 // Everything matched; can use monomorphic store. |
4810 BuildCheckHeapObject(object); | 4811 BuildCheckHeapObject(object); |
4811 Add<HCheckMaps>(object, types); | 4812 HCheckMaps* checked_object = Add<HCheckMaps>(object, types); |
4812 HInstruction* store; | 4813 HInstruction* store; |
4813 CHECK_ALIVE_OR_RETURN( | 4814 CHECK_ALIVE_OR_RETURN( |
4814 store = BuildStoreNamedField( | 4815 store = BuildStoreNamedField( |
4815 object, name, store_value, types->at(count - 1), &lookup), | 4816 checked_object, name, store_value, types->at(count - 1), &lookup), |
4816 true); | 4817 true); |
4817 if (!ast_context()->IsEffect()) Push(result_value); | 4818 if (!ast_context()->IsEffect()) Push(result_value); |
4818 store->set_position(position); | 4819 store->set_position(position); |
4819 AddInstruction(store); | 4820 AddInstruction(store); |
4820 Add<HSimulate>(assignment_id); | 4821 Add<HSimulate>(assignment_id); |
4821 if (!ast_context()->IsEffect()) Drop(1); | 4822 if (!ast_context()->IsEffect()) Drop(1); |
4822 ast_context()->ReturnValue(result_value); | 4823 ast_context()->ReturnValue(result_value); |
4823 return true; | 4824 return true; |
4824 } | 4825 } |
4825 | 4826 |
(...skipping 28 matching lines...) Expand all Loading... |
4854 ++count; | 4855 ++count; |
4855 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 4856 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
4856 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 4857 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
4857 HCompareMap* compare = | 4858 HCompareMap* compare = |
4858 new(zone()) HCompareMap(object, map, if_true, if_false); | 4859 new(zone()) HCompareMap(object, map, if_true, if_false); |
4859 current_block()->Finish(compare); | 4860 current_block()->Finish(compare); |
4860 | 4861 |
4861 set_current_block(if_true); | 4862 set_current_block(if_true); |
4862 HInstruction* instr; | 4863 HInstruction* instr; |
4863 CHECK_ALIVE(instr = BuildStoreNamedField( | 4864 CHECK_ALIVE(instr = BuildStoreNamedField( |
4864 object, name, store_value, map, &lookup)); | 4865 compare, name, store_value, map, &lookup)); |
4865 instr->set_position(position); | 4866 instr->set_position(position); |
4866 // Goto will add the HSimulate for the store. | 4867 // Goto will add the HSimulate for the store. |
4867 AddInstruction(instr); | 4868 AddInstruction(instr); |
4868 if (!ast_context()->IsEffect()) Push(result_value); | 4869 if (!ast_context()->IsEffect()) Push(result_value); |
4869 current_block()->Goto(join); | 4870 current_block()->Goto(join); |
4870 | 4871 |
4871 set_current_block(if_false); | 4872 set_current_block(if_false); |
4872 } | 4873 } |
4873 } | 4874 } |
4874 | 4875 |
(...skipping 4988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9863 if (ShouldProduceTraceOutput()) { | 9864 if (ShouldProduceTraceOutput()) { |
9864 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9865 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9865 } | 9866 } |
9866 | 9867 |
9867 #ifdef DEBUG | 9868 #ifdef DEBUG |
9868 graph_->Verify(false); // No full verify. | 9869 graph_->Verify(false); // No full verify. |
9869 #endif | 9870 #endif |
9870 } | 9871 } |
9871 | 9872 |
9872 } } // namespace v8::internal | 9873 } } // namespace v8::internal |
OLD | NEW |