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 4256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4267 switch (property->kind()) { | 4267 switch (property->kind()) { |
4268 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 4268 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
4269 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 4269 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
4270 // Fall through. | 4270 // Fall through. |
4271 case ObjectLiteral::Property::COMPUTED: | 4271 case ObjectLiteral::Property::COMPUTED: |
4272 if (key->handle()->IsSymbol()) { | 4272 if (key->handle()->IsSymbol()) { |
4273 if (property->emit_store()) { | 4273 if (property->emit_store()) { |
4274 property->RecordTypeFeedback(oracle()); | 4274 property->RecordTypeFeedback(oracle()); |
4275 CHECK_ALIVE(VisitForValue(value)); | 4275 CHECK_ALIVE(VisitForValue(value)); |
4276 HValue* value = Pop(); | 4276 HValue* value = Pop(); |
4277 HInstruction* store = BuildStoreNamed(literal, value, property); | 4277 HInstruction* store; |
| 4278 CHECK_ALIVE(store = BuildStoreNamed(literal, value, property)); |
4278 AddInstruction(store); | 4279 AddInstruction(store); |
4279 if (store->HasObservableSideEffects()) AddSimulate(key->id()); | 4280 if (store->HasObservableSideEffects()) AddSimulate(key->id()); |
4280 } else { | 4281 } else { |
4281 CHECK_ALIVE(VisitForEffect(value)); | 4282 CHECK_ALIVE(VisitForEffect(value)); |
4282 } | 4283 } |
4283 break; | 4284 break; |
4284 } | 4285 } |
4285 // Fall through. | 4286 // Fall through. |
4286 case ObjectLiteral::Property::PROTOTYPE: | 4287 case ObjectLiteral::Property::PROTOTYPE: |
4287 case ObjectLiteral::Property::SETTER: | 4288 case ObjectLiteral::Property::SETTER: |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4431 } | 4432 } |
4432 } | 4433 } |
4433 | 4434 |
4434 | 4435 |
4435 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, | 4436 HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, |
4436 Handle<String> name, | 4437 Handle<String> name, |
4437 HValue* value, | 4438 HValue* value, |
4438 Handle<Map> type, | 4439 Handle<Map> type, |
4439 LookupResult* lookup, | 4440 LookupResult* lookup, |
4440 bool smi_and_map_check) { | 4441 bool smi_and_map_check) { |
| 4442 ASSERT(lookup->IsFound()); |
4441 if (smi_and_map_check) { | 4443 if (smi_and_map_check) { |
4442 AddInstruction(new(zone()) HCheckNonSmi(object)); | 4444 AddInstruction(new(zone()) HCheckNonSmi(object)); |
4443 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); | 4445 AddInstruction(HCheckMaps::NewWithTransitions(object, type)); |
4444 } | 4446 } |
4445 | 4447 |
| 4448 // If the property does not exist yet, we have to check that it wasn't made |
| 4449 // readonly by some meanwhile modifications on the prototype chain. |
| 4450 if (!lookup->IsProperty()) { |
| 4451 Object* proto = type->prototype(); |
| 4452 // First check that the prototype chain isn't affected already. |
| 4453 LookupResult proto_result(isolate()); |
| 4454 proto->Lookup(*name, &proto_result); |
| 4455 if (proto_result.IsProperty()) { |
| 4456 // If the inherited property could induce readonly-ness, bail out. |
| 4457 if (proto_result.IsReadOnly() || !proto_result.IsCacheable()) { |
| 4458 Bailout("improper object on prototype chain for store"); |
| 4459 return NULL; |
| 4460 } |
| 4461 // We only need to check up to where the preexisting property. |
| 4462 proto = proto_result.holder(); |
| 4463 } else { |
| 4464 // Otherwise, find the top prototype. |
| 4465 while (proto->GetPrototype()->IsJSObject()) proto = proto->GetPrototype(); |
| 4466 } |
| 4467 ASSERT(proto->IsJSObject()); |
| 4468 AddInstruction(new(zone()) HCheckPrototypeMaps( |
| 4469 Handle<JSObject>(JSObject::cast(type->prototype())), |
| 4470 Handle<JSObject>(JSObject::cast(proto)))); |
| 4471 } |
| 4472 |
4446 int index = ComputeLoadStoreFieldIndex(type, name, lookup); | 4473 int index = ComputeLoadStoreFieldIndex(type, name, lookup); |
4447 bool is_in_object = index < 0; | 4474 bool is_in_object = index < 0; |
4448 int offset = index * kPointerSize; | 4475 int offset = index * kPointerSize; |
4449 if (index < 0) { | 4476 if (index < 0) { |
4450 // Negative property indices are in-object properties, indexed | 4477 // Negative property indices are in-object properties, indexed |
4451 // from the end of the fixed part of the object. | 4478 // from the end of the fixed part of the object. |
4452 offset += type->instance_size(); | 4479 offset += type->instance_size(); |
4453 } else { | 4480 } else { |
4454 offset += FixedArray::kHeaderSize; | 4481 offset += FixedArray::kHeaderSize; |
4455 } | 4482 } |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4592 join = graph()->CreateBasicBlock(); | 4619 join = graph()->CreateBasicBlock(); |
4593 } | 4620 } |
4594 ++count; | 4621 ++count; |
4595 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 4622 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
4596 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 4623 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
4597 HCompareMap* compare = | 4624 HCompareMap* compare = |
4598 new(zone()) HCompareMap(object, map, if_true, if_false); | 4625 new(zone()) HCompareMap(object, map, if_true, if_false); |
4599 current_block()->Finish(compare); | 4626 current_block()->Finish(compare); |
4600 | 4627 |
4601 set_current_block(if_true); | 4628 set_current_block(if_true); |
4602 HInstruction* instr = | 4629 HInstruction* instr; |
4603 BuildStoreNamedField(object, name, value, map, &lookup, false); | 4630 CHECK_ALIVE(instr = |
| 4631 BuildStoreNamedField(object, name, value, map, &lookup, false)); |
4604 instr->set_position(expr->position()); | 4632 instr->set_position(expr->position()); |
4605 // Goto will add the HSimulate for the store. | 4633 // Goto will add the HSimulate for the store. |
4606 AddInstruction(instr); | 4634 AddInstruction(instr); |
4607 if (!ast_context()->IsEffect()) Push(value); | 4635 if (!ast_context()->IsEffect()) Push(value); |
4608 current_block()->Goto(join); | 4636 current_block()->Goto(join); |
4609 | 4637 |
4610 set_current_block(if_false); | 4638 set_current_block(if_false); |
4611 } | 4639 } |
4612 } | 4640 } |
4613 | 4641 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4661 // Named store. | 4689 // Named store. |
4662 CHECK_ALIVE(VisitForValue(expr->value())); | 4690 CHECK_ALIVE(VisitForValue(expr->value())); |
4663 value = Pop(); | 4691 value = Pop(); |
4664 HValue* object = Pop(); | 4692 HValue* object = Pop(); |
4665 | 4693 |
4666 Literal* key = prop->key()->AsLiteral(); | 4694 Literal* key = prop->key()->AsLiteral(); |
4667 Handle<String> name = Handle<String>::cast(key->handle()); | 4695 Handle<String> name = Handle<String>::cast(key->handle()); |
4668 ASSERT(!name.is_null()); | 4696 ASSERT(!name.is_null()); |
4669 | 4697 |
4670 SmallMapList* types = expr->GetReceiverTypes(); | 4698 SmallMapList* types = expr->GetReceiverTypes(); |
4671 LookupResult lookup(isolate()); | |
4672 | |
4673 if (expr->IsMonomorphic()) { | 4699 if (expr->IsMonomorphic()) { |
4674 instr = BuildStoreNamed(object, value, expr); | 4700 CHECK_ALIVE(instr = BuildStoreNamed(object, value, expr)); |
4675 | 4701 |
4676 } else if (types != NULL && types->length() > 1) { | 4702 } else if (types != NULL && types->length() > 1) { |
4677 HandlePolymorphicStoreNamedField(expr, object, value, types, name); | 4703 HandlePolymorphicStoreNamedField(expr, object, value, types, name); |
4678 return; | 4704 return; |
4679 | 4705 |
4680 } else { | 4706 } else { |
4681 instr = BuildStoreNamedGeneric(object, name, value); | 4707 instr = BuildStoreNamedGeneric(object, name, value); |
4682 } | 4708 } |
4683 | 4709 |
4684 } else { | 4710 } else { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4843 if (load->HasObservableSideEffects()) AddSimulate(expr->CompoundLoadId()); | 4869 if (load->HasObservableSideEffects()) AddSimulate(expr->CompoundLoadId()); |
4844 | 4870 |
4845 CHECK_ALIVE(VisitForValue(expr->value())); | 4871 CHECK_ALIVE(VisitForValue(expr->value())); |
4846 HValue* right = Pop(); | 4872 HValue* right = Pop(); |
4847 HValue* left = Pop(); | 4873 HValue* left = Pop(); |
4848 | 4874 |
4849 HInstruction* instr = BuildBinaryOperation(operation, left, right); | 4875 HInstruction* instr = BuildBinaryOperation(operation, left, right); |
4850 PushAndAdd(instr); | 4876 PushAndAdd(instr); |
4851 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); | 4877 if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
4852 | 4878 |
4853 HInstruction* store = BuildStoreNamed(obj, instr, prop); | 4879 HInstruction* store; |
| 4880 CHECK_ALIVE(store = BuildStoreNamed(obj, instr, prop)); |
4854 AddInstruction(store); | 4881 AddInstruction(store); |
4855 // Drop the simulated receiver and value. Return the value. | 4882 // Drop the simulated receiver and value. Return the value. |
4856 Drop(2); | 4883 Drop(2); |
4857 Push(instr); | 4884 Push(instr); |
4858 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); | 4885 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); |
4859 return ast_context()->ReturnValue(Pop()); | 4886 return ast_context()->ReturnValue(Pop()); |
4860 | 4887 |
4861 } else { | 4888 } else { |
4862 // Keyed property. | 4889 // Keyed property. |
4863 CHECK_ALIVE(VisitForValue(prop->obj())); | 4890 CHECK_ALIVE(VisitForValue(prop->obj())); |
(...skipping 2229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7093 load = BuildLoadNamed(obj, prop, map, name); | 7120 load = BuildLoadNamed(obj, prop, map, name); |
7094 } else { | 7121 } else { |
7095 load = BuildLoadNamedGeneric(obj, prop); | 7122 load = BuildLoadNamedGeneric(obj, prop); |
7096 } | 7123 } |
7097 PushAndAdd(load); | 7124 PushAndAdd(load); |
7098 if (load->HasObservableSideEffects()) AddSimulate(expr->CountId()); | 7125 if (load->HasObservableSideEffects()) AddSimulate(expr->CountId()); |
7099 | 7126 |
7100 after = BuildIncrement(returns_original_input, expr); | 7127 after = BuildIncrement(returns_original_input, expr); |
7101 input = Pop(); | 7128 input = Pop(); |
7102 | 7129 |
7103 HInstruction* store = BuildStoreNamed(obj, after, prop); | 7130 HInstruction* store; |
| 7131 CHECK_ALIVE(store = BuildStoreNamed(obj, after, prop)); |
7104 AddInstruction(store); | 7132 AddInstruction(store); |
7105 | 7133 |
7106 // Overwrite the receiver in the bailout environment with the result | 7134 // Overwrite the receiver in the bailout environment with the result |
7107 // of the operation, and the placeholder with the original value if | 7135 // of the operation, and the placeholder with the original value if |
7108 // necessary. | 7136 // necessary. |
7109 environment()->SetExpressionStackAt(0, after); | 7137 environment()->SetExpressionStackAt(0, after); |
7110 if (returns_original_input) environment()->SetExpressionStackAt(1, input); | 7138 if (returns_original_input) environment()->SetExpressionStackAt(1, input); |
7111 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); | 7139 if (store->HasObservableSideEffects()) AddSimulate(expr->AssignmentId()); |
7112 | 7140 |
7113 } else { | 7141 } else { |
(...skipping 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8860 } | 8888 } |
8861 } | 8889 } |
8862 | 8890 |
8863 #ifdef DEBUG | 8891 #ifdef DEBUG |
8864 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 8892 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
8865 if (allocator_ != NULL) allocator_->Verify(); | 8893 if (allocator_ != NULL) allocator_->Verify(); |
8866 #endif | 8894 #endif |
8867 } | 8895 } |
8868 | 8896 |
8869 } } // namespace v8::internal | 8897 } } // namespace v8::internal |
OLD | NEW |