OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 3377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3388 HValue* value, | 3388 HValue* value, |
3389 Expression* expr) { | 3389 Expression* expr) { |
3390 Property* prop = (expr->AsProperty() != NULL) | 3390 Property* prop = (expr->AsProperty() != NULL) |
3391 ? expr->AsProperty() | 3391 ? expr->AsProperty() |
3392 : expr->AsAssignment()->target()->AsProperty(); | 3392 : expr->AsAssignment()->target()->AsProperty(); |
3393 Literal* key = prop->key()->AsLiteral(); | 3393 Literal* key = prop->key()->AsLiteral(); |
3394 Handle<String> name = Handle<String>::cast(key->handle()); | 3394 Handle<String> name = Handle<String>::cast(key->handle()); |
3395 ASSERT(!name.is_null()); | 3395 ASSERT(!name.is_null()); |
3396 | 3396 |
3397 LookupResult lookup; | 3397 LookupResult lookup; |
3398 ZoneMapList* types = expr->GetReceiverTypes(); | 3398 SmallMapList* types = expr->GetReceiverTypes(); |
3399 bool is_monomorphic = expr->IsMonomorphic() && | 3399 bool is_monomorphic = expr->IsMonomorphic() && |
3400 ComputeStoredField(types->first(), name, &lookup); | 3400 ComputeStoredField(types->first(), name, &lookup); |
3401 | 3401 |
3402 return is_monomorphic | 3402 return is_monomorphic |
3403 ? BuildStoreNamedField(object, name, value, types->first(), &lookup, | 3403 ? BuildStoreNamedField(object, name, value, types->first(), &lookup, |
3404 true) // Needs smi and map check. | 3404 true) // Needs smi and map check. |
3405 : BuildStoreNamedGeneric(object, name, value); | 3405 : BuildStoreNamedGeneric(object, name, value); |
3406 } | 3406 } |
3407 | 3407 |
3408 | 3408 |
3409 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, | 3409 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, |
3410 HValue* object, | 3410 HValue* object, |
3411 HValue* value, | 3411 HValue* value, |
3412 ZoneMapList* types, | 3412 SmallMapList* types, |
3413 Handle<String> name) { | 3413 Handle<String> name) { |
3414 // TODO(ager): We should recognize when the prototype chains for different | 3414 // TODO(ager): We should recognize when the prototype chains for different |
3415 // maps are identical. In that case we can avoid repeatedly generating the | 3415 // maps are identical. In that case we can avoid repeatedly generating the |
3416 // same prototype map checks. | 3416 // same prototype map checks. |
3417 int count = 0; | 3417 int count = 0; |
3418 HBasicBlock* join = NULL; | 3418 HBasicBlock* join = NULL; |
3419 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { | 3419 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { |
3420 Handle<Map> map = types->at(i); | 3420 Handle<Map> map = types->at(i); |
3421 LookupResult lookup; | 3421 LookupResult lookup; |
3422 if (ComputeStoredField(map, name, &lookup)) { | 3422 if (ComputeStoredField(map, name, &lookup)) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3493 if (prop->key()->IsPropertyName()) { | 3493 if (prop->key()->IsPropertyName()) { |
3494 // Named store. | 3494 // Named store. |
3495 CHECK_ALIVE(VisitForValue(expr->value())); | 3495 CHECK_ALIVE(VisitForValue(expr->value())); |
3496 value = Pop(); | 3496 value = Pop(); |
3497 HValue* object = Pop(); | 3497 HValue* object = Pop(); |
3498 | 3498 |
3499 Literal* key = prop->key()->AsLiteral(); | 3499 Literal* key = prop->key()->AsLiteral(); |
3500 Handle<String> name = Handle<String>::cast(key->handle()); | 3500 Handle<String> name = Handle<String>::cast(key->handle()); |
3501 ASSERT(!name.is_null()); | 3501 ASSERT(!name.is_null()); |
3502 | 3502 |
3503 ZoneMapList* types = expr->GetReceiverTypes(); | 3503 SmallMapList* types = expr->GetReceiverTypes(); |
3504 LookupResult lookup; | 3504 LookupResult lookup; |
3505 | 3505 |
3506 if (expr->IsMonomorphic()) { | 3506 if (expr->IsMonomorphic()) { |
3507 instr = BuildStoreNamed(object, value, expr); | 3507 instr = BuildStoreNamed(object, value, expr); |
3508 | 3508 |
3509 } else if (types != NULL && types->length() > 1) { | 3509 } else if (types != NULL && types->length() > 1) { |
3510 HandlePolymorphicStoreNamedField(expr, object, value, types, name); | 3510 HandlePolymorphicStoreNamedField(expr, object, value, types, name); |
3511 return; | 3511 return; |
3512 | 3512 |
3513 } else { | 3513 } else { |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3979 HValue* key, | 3979 HValue* key, |
3980 HValue* val, | 3980 HValue* val, |
3981 Expression* prop, | 3981 Expression* prop, |
3982 int ast_id, | 3982 int ast_id, |
3983 int position, | 3983 int position, |
3984 bool is_store, | 3984 bool is_store, |
3985 bool* has_side_effects) { | 3985 bool* has_side_effects) { |
3986 *has_side_effects = false; | 3986 *has_side_effects = false; |
3987 AddInstruction(new(zone()) HCheckNonSmi(object)); | 3987 AddInstruction(new(zone()) HCheckNonSmi(object)); |
3988 AddInstruction(HCheckInstanceType::NewIsSpecObject(object)); | 3988 AddInstruction(HCheckInstanceType::NewIsSpecObject(object)); |
3989 ZoneMapList* maps = prop->GetReceiverTypes(); | 3989 SmallMapList* maps = prop->GetReceiverTypes(); |
3990 bool todo_external_array = false; | 3990 bool todo_external_array = false; |
3991 | 3991 |
3992 static const int kNumElementTypes = JSObject::kElementsKindCount; | 3992 static const int kNumElementTypes = JSObject::kElementsKindCount; |
3993 bool type_todo[kNumElementTypes]; | 3993 bool type_todo[kNumElementTypes]; |
3994 for (int i = 0; i < kNumElementTypes; ++i) { | 3994 for (int i = 0; i < kNumElementTypes; ++i) { |
3995 type_todo[i] = false; | 3995 type_todo[i] = false; |
3996 } | 3996 } |
3997 | 3997 |
3998 for (int i = 0; i < maps->length(); ++i) { | 3998 for (int i = 0; i < maps->length(); ++i) { |
3999 ASSERT(maps->at(i)->IsMap()); | 3999 ASSERT(maps->at(i)->IsMap()); |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4253 AddInstruction(char_code); | 4253 AddInstruction(char_code); |
4254 instr = new(zone()) HStringCharFromCode(context, char_code); | 4254 instr = new(zone()) HStringCharFromCode(context, char_code); |
4255 | 4255 |
4256 } else if (expr->IsFunctionPrototype()) { | 4256 } else if (expr->IsFunctionPrototype()) { |
4257 HValue* function = Pop(); | 4257 HValue* function = Pop(); |
4258 AddInstruction(new(zone()) HCheckNonSmi(function)); | 4258 AddInstruction(new(zone()) HCheckNonSmi(function)); |
4259 instr = new(zone()) HLoadFunctionPrototype(function); | 4259 instr = new(zone()) HLoadFunctionPrototype(function); |
4260 | 4260 |
4261 } else if (expr->key()->IsPropertyName()) { | 4261 } else if (expr->key()->IsPropertyName()) { |
4262 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 4262 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
4263 ZoneMapList* types = expr->GetReceiverTypes(); | 4263 SmallMapList* types = expr->GetReceiverTypes(); |
4264 | 4264 |
4265 HValue* obj = Pop(); | 4265 HValue* obj = Pop(); |
4266 if (expr->IsMonomorphic()) { | 4266 if (expr->IsMonomorphic()) { |
4267 instr = BuildLoadNamed(obj, expr, types->first(), name); | 4267 instr = BuildLoadNamed(obj, expr, types->first(), name); |
4268 } else if (types != NULL && types->length() > 1) { | 4268 } else if (types != NULL && types->length() > 1) { |
4269 AddInstruction(new(zone()) HCheckNonSmi(obj)); | 4269 AddInstruction(new(zone()) HCheckNonSmi(obj)); |
4270 HValue* context = environment()->LookupContext(); | 4270 HValue* context = environment()->LookupContext(); |
4271 instr = new(zone()) HLoadNamedFieldPolymorphic(context, obj, types, name); | 4271 instr = new(zone()) HLoadNamedFieldPolymorphic(context, obj, types, name); |
4272 } else { | 4272 } else { |
4273 instr = BuildLoadNamedGeneric(obj, expr); | 4273 instr = BuildLoadNamedGeneric(obj, expr); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4314 if (!expr->holder().is_null()) { | 4314 if (!expr->holder().is_null()) { |
4315 AddInstruction(new(zone()) HCheckPrototypeMaps( | 4315 AddInstruction(new(zone()) HCheckPrototypeMaps( |
4316 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), | 4316 Handle<JSObject>(JSObject::cast(receiver_map->prototype())), |
4317 expr->holder())); | 4317 expr->holder())); |
4318 } | 4318 } |
4319 } | 4319 } |
4320 | 4320 |
4321 | 4321 |
4322 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr, | 4322 void HGraphBuilder::HandlePolymorphicCallNamed(Call* expr, |
4323 HValue* receiver, | 4323 HValue* receiver, |
4324 ZoneMapList* types, | 4324 SmallMapList* types, |
4325 Handle<String> name) { | 4325 Handle<String> name) { |
4326 // TODO(ager): We should recognize when the prototype chains for different | 4326 // TODO(ager): We should recognize when the prototype chains for different |
4327 // maps are identical. In that case we can avoid repeatedly generating the | 4327 // maps are identical. In that case we can avoid repeatedly generating the |
4328 // same prototype map checks. | 4328 // same prototype map checks. |
4329 int argument_count = expr->arguments()->length() + 1; // Includes receiver. | 4329 int argument_count = expr->arguments()->length() + 1; // Includes receiver. |
4330 int count = 0; | 4330 int count = 0; |
4331 HBasicBlock* join = NULL; | 4331 HBasicBlock* join = NULL; |
4332 for (int i = 0; i < types->length() && count < kMaxCallPolymorphism; ++i) { | 4332 for (int i = 0; i < types->length() && count < kMaxCallPolymorphism; ++i) { |
4333 Handle<Map> map = types->at(i); | 4333 Handle<Map> map = types->at(i); |
4334 if (expr->ComputeTarget(map, name)) { | 4334 if (expr->ComputeTarget(map, name)) { |
(...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4842 // Named function call. | 4842 // Named function call. |
4843 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); | 4843 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); |
4844 | 4844 |
4845 if (TryCallApply(expr)) return; | 4845 if (TryCallApply(expr)) return; |
4846 | 4846 |
4847 CHECK_ALIVE(VisitForValue(prop->obj())); | 4847 CHECK_ALIVE(VisitForValue(prop->obj())); |
4848 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4848 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
4849 | 4849 |
4850 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 4850 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
4851 | 4851 |
4852 ZoneMapList* types = expr->GetReceiverTypes(); | 4852 SmallMapList* types = expr->GetReceiverTypes(); |
4853 | 4853 |
4854 HValue* receiver = | 4854 HValue* receiver = |
4855 environment()->ExpressionStackAt(expr->arguments()->length()); | 4855 environment()->ExpressionStackAt(expr->arguments()->length()); |
4856 if (expr->IsMonomorphic()) { | 4856 if (expr->IsMonomorphic()) { |
4857 Handle<Map> receiver_map = | 4857 Handle<Map> receiver_map = (types == NULL || types->is_empty()) |
4858 (types == NULL) ? Handle<Map>::null() : types->first(); | 4858 ? Handle<Map>::null() |
| 4859 : types->first(); |
4859 if (TryInlineBuiltinFunction(expr, | 4860 if (TryInlineBuiltinFunction(expr, |
4860 receiver, | 4861 receiver, |
4861 receiver_map, | 4862 receiver_map, |
4862 expr->check_type())) { | 4863 expr->check_type())) { |
4863 return; | 4864 return; |
4864 } | 4865 } |
4865 | 4866 |
4866 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) || | 4867 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) || |
4867 expr->check_type() != RECEIVER_MAP_CHECK) { | 4868 expr->check_type() != RECEIVER_MAP_CHECK) { |
4868 // When the target has a custom call IC generator, use the IC, | 4869 // When the target has a custom call IC generator, use the IC, |
(...skipping 1880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6749 } | 6750 } |
6750 } | 6751 } |
6751 | 6752 |
6752 #ifdef DEBUG | 6753 #ifdef DEBUG |
6753 if (graph_ != NULL) graph_->Verify(); | 6754 if (graph_ != NULL) graph_->Verify(); |
6754 if (allocator_ != NULL) allocator_->Verify(); | 6755 if (allocator_ != NULL) allocator_->Verify(); |
6755 #endif | 6756 #endif |
6756 } | 6757 } |
6757 | 6758 |
6758 } } // namespace v8::internal | 6759 } } // namespace v8::internal |
OLD | NEW |