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 4473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4484 switch (property->kind()) { | 4484 switch (property->kind()) { |
4485 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 4485 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
4486 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 4486 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
4487 // Fall through. | 4487 // Fall through. |
4488 case ObjectLiteral::Property::COMPUTED: | 4488 case ObjectLiteral::Property::COMPUTED: |
4489 if (key->handle()->IsSymbol()) { | 4489 if (key->handle()->IsSymbol()) { |
4490 if (property->emit_store()) { | 4490 if (property->emit_store()) { |
4491 property->RecordTypeFeedback(oracle()); | 4491 property->RecordTypeFeedback(oracle()); |
4492 CHECK_ALIVE(VisitForValue(value)); | 4492 CHECK_ALIVE(VisitForValue(value)); |
4493 HValue* value = Pop(); | 4493 HValue* value = Pop(); |
4494 HInstruction* store; | 4494 HInstruction* store = BuildStoreNamed(literal, value, property); |
4495 CHECK_ALIVE(store = BuildStoreNamed(literal, value, property)); | |
4496 AddInstruction(store); | 4495 AddInstruction(store); |
4497 if (store->HasObservableSideEffects()) AddSimulate(key->id()); | 4496 if (store->HasObservableSideEffects()) AddSimulate(key->id()); |
4498 } else { | 4497 } else { |
4499 CHECK_ALIVE(VisitForEffect(value)); | 4498 CHECK_ALIVE(VisitForEffect(value)); |
4500 } | 4499 } |
4501 break; | 4500 break; |
4502 } | 4501 } |
4503 // Fall through. | 4502 // Fall through. |
4504 case ObjectLiteral::Property::PROTOTYPE: | 4503 case ObjectLiteral::Property::PROTOTYPE: |
4505 case ObjectLiteral::Property::SETTER: | 4504 case ObjectLiteral::Property::SETTER: |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4652 } | 4651 } |
4653 } | 4652 } |
4654 | 4653 |
4655 | 4654 |
4656 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, | 4655 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, |
4657 Handle<String> name, | 4656 Handle<String> name, |
4658 HValue* value, | 4657 HValue* value, |
4659 Handle<Map> type, | 4658 Handle<Map> type, |
4660 LookupResult* lookup, | 4659 LookupResult* lookup, |
4661 bool smi_and_map_check) { | 4660 bool smi_and_map_check) { |
4662 ASSERT(lookup->IsFound()); | |
4663 if (smi_and_map_check) { | 4661 if (smi_and_map_check) { |
4664 AddInstruction(new(zone()) HCheckNonSmi(object)); | 4662 AddInstruction(new(zone()) HCheckNonSmi(object)); |
4665 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); | 4663 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); |
4666 } | 4664 } |
4667 | 4665 |
4668 // If the property does not exist yet, we have to check that it wasn't made | |
4669 // readonly or turned into a setter by some meanwhile modifications on the | |
4670 // prototype chain. | |
4671 if (!lookup->IsProperty()) { | |
4672 Object* proto = type->prototype(); | |
4673 // First check that the prototype chain isn't affected already. | |
4674 LookupResult proto_result(isolate()); | |
4675 proto->Lookup(*name, &proto_result); | |
4676 if (proto_result.IsProperty()) { | |
4677 // If the inherited property could induce readonly-ness, bail out. | |
4678 if (proto_result.IsReadOnly() || !proto_result.IsCacheable()) { | |
4679 Bailout("improper object on prototype chain for store"); | |
4680 return NULL; | |
4681 } | |
4682 // We only need to check up to the preexisting property. | |
4683 proto = proto_result.holder(); | |
4684 } else { | |
4685 // Otherwise, find the top prototype. | |
4686 while (proto->GetPrototype()->IsJSObject()) proto = proto->GetPrototype(); | |
4687 ASSERT(proto->GetPrototype()->IsNull()); | |
4688 } | |
4689 ASSERT(proto->IsJSObject()); | |
4690 AddInstruction(new(zone()) HCheckPrototypeMaps( | |
4691 Handle<JSObject>(JSObject::cast(type->prototype())), | |
4692 Handle<JSObject>(JSObject::cast(proto)))); | |
4693 } | |
4694 | |
4695 int index = ComputeLoadStoreFieldIndex(type, name, lookup); | 4666 int index = ComputeLoadStoreFieldIndex(type, name, lookup); |
4696 bool is_in_object = index < 0; | 4667 bool is_in_object = index < 0; |
4697 int offset = index * kPointerSize; | 4668 int offset = index * kPointerSize; |
4698 if (index < 0) { | 4669 if (index < 0) { |
4699 // Negative property indices are in-object properties, indexed | 4670 // Negative property indices are in-object properties, indexed |
4700 // from the end of the fixed part of the object. | 4671 // from the end of the fixed part of the object. |
4701 offset += type->instance_size(); | 4672 offset += type->instance_size(); |
4702 } else { | 4673 } else { |
4703 offset += FixedArray::kHeaderSize; | 4674 offset += FixedArray::kHeaderSize; |
4704 } | 4675 } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4841 join = graph()->CreateBasicBlock(); | 4812 join = graph()->CreateBasicBlock(); |
4842 } | 4813 } |
4843 ++count; | 4814 ++count; |
4844 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 4815 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
4845 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 4816 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
4846 HCompareMap* compare = | 4817 HCompareMap* compare = |
4847 new(zone()) HCompareMap(object, map, if_true, if_false); | 4818 new(zone()) HCompareMap(object, map, if_true, if_false); |
4848 current_block()->Finish(compare); | 4819 current_block()->Finish(compare); |
4849 | 4820 |
4850 set_current_block(if_true); | 4821 set_current_block(if_true); |
4851 HInstruction* instr; | 4822 HInstruction* instr = |
4852 CHECK_ALIVE(instr = | 4823 BuildStoreNamedField(object, name, value, map, &lookup, false); |
4853 BuildStoreNamedField(object, name, value, map, &lookup, false)); | |
4854 instr->set_position(expr->position()); | 4824 instr->set_position(expr->position()); |
4855 // Goto will add the HSimulate for the store. | 4825 // Goto will add the HSimulate for the store. |
4856 AddInstruction(instr); | 4826 AddInstruction(instr); |
4857 if (!ast_context()->IsEffect()) Push(value); | 4827 if (!ast_context()->IsEffect()) Push(value); |
4858 current_block()->Goto(join); | 4828 current_block()->Goto(join); |
4859 | 4829 |
4860 set_current_block(if_false); | 4830 set_current_block(if_false); |
4861 } | 4831 } |
4862 } | 4832 } |
4863 | 4833 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4911 // Named store. | 4881 // Named store. |
4912 CHECK_ALIVE(VisitForValue(expr->value())); | 4882 CHECK_ALIVE(VisitForValue(expr->value())); |
4913 value = Pop(); | 4883 value = Pop(); |
4914 HValue* object = Pop(); | 4884 HValue* object = Pop(); |
4915 | 4885 |
4916 Literal* key = prop->key()->AsLiteral(); | 4886 Literal* key = prop->key()->AsLiteral(); |
4917 Handle<String> name = Handle<String>::cast(key->handle()); | 4887 Handle<String> name = Handle<String>::cast(key->handle()); |
4918 ASSERT(!name.is_null()); | 4888 ASSERT(!name.is_null()); |
4919 | 4889 |
4920 SmallMapList* types = expr->GetReceiverTypes(); | 4890 SmallMapList* types = expr->GetReceiverTypes(); |
| 4891 LookupResult lookup(isolate()); |
| 4892 |
4921 if (expr->IsMonomorphic()) { | 4893 if (expr->IsMonomorphic()) { |
4922 CHECK_ALIVE(instr = BuildStoreNamed(object, value, expr)); | 4894 instr = BuildStoreNamed(object, value, expr); |
4923 | 4895 |
4924 } else if (types != NULL && types->length() > 1) { | 4896 } else if (types != NULL && types->length() > 1) { |
4925 HandlePolymorphicStoreNamedField(expr, object, value, types, name); | 4897 HandlePolymorphicStoreNamedField(expr, object, value, types, name); |
4926 return; | 4898 return; |
4927 | 4899 |
4928 } else { | 4900 } else { |
4929 instr = BuildStoreNamedGeneric(object, name, value); | 4901 instr = BuildStoreNamedGeneric(object, name, value); |
4930 } | 4902 } |
4931 | 4903 |
4932 } else { | 4904 } else { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5091 if (load->HasObservableSideEffects()) AddSimulate(expr->CompoundLoadId()); | 5063 if (load->HasObservableSideEffects()) AddSimulate(expr->CompoundLoadId()); |
5092 | 5064 |
5093 CHECK_ALIVE(VisitForValue(expr->value())); | 5065 CHECK_ALIVE(VisitForValue(expr->value())); |
5094 HValue* right = Pop(); | 5066 HValue* right = Pop(); |
5095 HValue* left = Pop(); | 5067 HValue* left = Pop(); |
5096 | 5068 |
5097 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 5069 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
5098 PushAndAdd(instr); | 5070 PushAndAdd(instr); |
5099 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); | 5071 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
5100 | 5072 |
5101 HInstruction* store; | 5073 HInstruction* store = BuildStoreNamed(obj, instr, prop); |
5102 CHECK_ALIVE(store = BuildStoreNamed(obj, instr, prop)); | |
5103 AddInstruction(store); | 5074 AddInstruction(store); |
5104 // Drop the simulated receiver and value. Return the value. | 5075 // Drop the simulated receiver and value. Return the value. |
5105 Drop(2); | 5076 Drop(2); |
5106 Push(instr); | 5077 Push(instr); |
5107 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); | 5078 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); |
5108 return ast_context()->ReturnValue(Pop()); | 5079 return ast_context()->ReturnValue(Pop()); |
5109 | 5080 |
5110 } else { | 5081 } else { |
5111 // Keyed property. | 5082 // Keyed property. |
5112 CHECK_ALIVE(VisitForValue(prop->obj())); | 5083 CHECK_ALIVE(VisitForValue(prop->obj())); |
(...skipping 2254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7367 load = BuildLoadNamed(obj, prop, map, name); | 7338 load = BuildLoadNamed(obj, prop, map, name); |
7368 } else { | 7339 } else { |
7369 load = BuildLoadNamedGeneric(obj, prop); | 7340 load = BuildLoadNamedGeneric(obj, prop); |
7370 } | 7341 } |
7371 PushAndAdd(load); | 7342 PushAndAdd(load); |
7372 if (load->HasObservableSideEffects()) AddSimulate(expr->CountId()); | 7343 if (load->HasObservableSideEffects()) AddSimulate(expr->CountId()); |
7373 | 7344 |
7374 after = BuildIncrement(returns_original_input, expr); | 7345 after = BuildIncrement(returns_original_input, expr); |
7375 input = Pop(); | 7346 input = Pop(); |
7376 | 7347 |
7377 HInstruction* store; | 7348 HInstruction* store = BuildStoreNamed(obj, after, prop); |
7378 CHECK_ALIVE(store = BuildStoreNamed(obj, after, prop)); | |
7379 AddInstruction(store); | 7349 AddInstruction(store); |
7380 | 7350 |
7381 // Overwrite the receiver in the bailout environment with the result | 7351 // Overwrite the receiver in the bailout environment with the result |
7382 // of the operation, and the placeholder with the original value if | 7352 // of the operation, and the placeholder with the original value if |
7383 // necessary. | 7353 // necessary. |
7384 environment()->SetExpressionStackAt(0, after); | 7354 environment()->SetExpressionStackAt(0, after); |
7385 if (returns_original_input) environment()->SetExpressionStackAt(1, input); | 7355 if (returns_original_input) environment()->SetExpressionStackAt(1, input); |
7386 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); | 7356 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); |
7387 | 7357 |
7388 } else { | 7358 } else { |
(...skipping 1738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9127 } | 9097 } |
9128 } | 9098 } |
9129 | 9099 |
9130 #ifdef DEBUG | 9100 #ifdef DEBUG |
9131 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 9101 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
9132 if (allocator_ != NULL) allocator_->Verify(); | 9102 if (allocator_ != NULL) allocator_->Verify(); |
9133 #endif | 9103 #endif |
9134 } | 9104 } |
9135 | 9105 |
9136 } } // namespace v8::internal | 9106 } } // namespace v8::internal |
OLD | NEW |