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 3138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3149 // Handle known global constants like 'undefined' specially to avoid a | 3149 // Handle known global constants like 'undefined' specially to avoid a |
3150 // load from a global cell for them. | 3150 // load from a global cell for them. |
3151 Handle<Object> constant_value = | 3151 Handle<Object> constant_value = |
3152 isolate()->factory()->GlobalConstantFor(variable->name()); | 3152 isolate()->factory()->GlobalConstantFor(variable->name()); |
3153 if (!constant_value.is_null()) { | 3153 if (!constant_value.is_null()) { |
3154 HConstant* instr = | 3154 HConstant* instr = |
3155 new(zone()) HConstant(constant_value, Representation::Tagged()); | 3155 new(zone()) HConstant(constant_value, Representation::Tagged()); |
3156 return ast_context()->ReturnInstruction(instr, expr->id()); | 3156 return ast_context()->ReturnInstruction(instr, expr->id()); |
3157 } | 3157 } |
3158 | 3158 |
3159 LookupResult lookup; | 3159 LookupResult lookup(isolate()); |
3160 GlobalPropertyAccess type = | 3160 GlobalPropertyAccess type = |
3161 LookupGlobalProperty(variable, &lookup, false); | 3161 LookupGlobalProperty(variable, &lookup, false); |
3162 | 3162 |
3163 if (type == kUseCell && | 3163 if (type == kUseCell && |
3164 info()->global_object()->IsAccessCheckNeeded()) { | 3164 info()->global_object()->IsAccessCheckNeeded()) { |
3165 type = kUseGeneric; | 3165 type = kUseGeneric; |
3166 } | 3166 } |
3167 | 3167 |
3168 if (type == kUseCell) { | 3168 if (type == kUseCell) { |
3169 Handle<GlobalObject> global(info()->global_object()); | 3169 Handle<GlobalObject> global(info()->global_object()); |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3464 HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, | 3464 HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, |
3465 HValue* value, | 3465 HValue* value, |
3466 Expression* expr) { | 3466 Expression* expr) { |
3467 Property* prop = (expr->AsProperty() != NULL) | 3467 Property* prop = (expr->AsProperty() != NULL) |
3468 ? expr->AsProperty() | 3468 ? expr->AsProperty() |
3469 : expr->AsAssignment()->target()->AsProperty(); | 3469 : expr->AsAssignment()->target()->AsProperty(); |
3470 Literal* key = prop->key()->AsLiteral(); | 3470 Literal* key = prop->key()->AsLiteral(); |
3471 Handle<String> name = Handle<String>::cast(key->handle()); | 3471 Handle<String> name = Handle<String>::cast(key->handle()); |
3472 ASSERT(!name.is_null()); | 3472 ASSERT(!name.is_null()); |
3473 | 3473 |
3474 LookupResult lookup; | 3474 LookupResult lookup(isolate()); |
3475 SmallMapList* types = expr->GetReceiverTypes(); | 3475 SmallMapList* types = expr->GetReceiverTypes(); |
3476 bool is_monomorphic = expr->IsMonomorphic() && | 3476 bool is_monomorphic = expr->IsMonomorphic() && |
3477 ComputeStoredField(types->first(), name, &lookup); | 3477 ComputeStoredField(types->first(), name, &lookup); |
3478 | 3478 |
3479 return is_monomorphic | 3479 return is_monomorphic |
3480 ? BuildStoreNamedField(object, name, value, types->first(), &lookup, | 3480 ? BuildStoreNamedField(object, name, value, types->first(), &lookup, |
3481 true) // Needs smi and map check. | 3481 true) // Needs smi and map check. |
3482 : BuildStoreNamedGeneric(object, name, value); | 3482 : BuildStoreNamedGeneric(object, name, value); |
3483 } | 3483 } |
3484 | 3484 |
3485 | 3485 |
3486 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, | 3486 void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, |
3487 HValue* object, | 3487 HValue* object, |
3488 HValue* value, | 3488 HValue* value, |
3489 SmallMapList* types, | 3489 SmallMapList* types, |
3490 Handle<String> name) { | 3490 Handle<String> name) { |
3491 // TODO(ager): We should recognize when the prototype chains for different | 3491 // TODO(ager): We should recognize when the prototype chains for different |
3492 // maps are identical. In that case we can avoid repeatedly generating the | 3492 // maps are identical. In that case we can avoid repeatedly generating the |
3493 // same prototype map checks. | 3493 // same prototype map checks. |
3494 int count = 0; | 3494 int count = 0; |
3495 HBasicBlock* join = NULL; | 3495 HBasicBlock* join = NULL; |
3496 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { | 3496 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { |
3497 Handle<Map> map = types->at(i); | 3497 Handle<Map> map = types->at(i); |
3498 LookupResult lookup; | 3498 LookupResult lookup(isolate()); |
3499 if (ComputeStoredField(map, name, &lookup)) { | 3499 if (ComputeStoredField(map, name, &lookup)) { |
3500 if (count == 0) { | 3500 if (count == 0) { |
3501 AddInstruction(new(zone()) HCheckNonSmi(object)); // Only needed once. | 3501 AddInstruction(new(zone()) HCheckNonSmi(object)); // Only needed once. |
3502 join = graph()->CreateBasicBlock(); | 3502 join = graph()->CreateBasicBlock(); |
3503 } | 3503 } |
3504 ++count; | 3504 ++count; |
3505 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 3505 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
3506 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 3506 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
3507 HCompareMap* compare = | 3507 HCompareMap* compare = |
3508 new(zone()) HCompareMap(object, map, if_true, if_false); | 3508 new(zone()) HCompareMap(object, map, if_true, if_false); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3571 // Named store. | 3571 // Named store. |
3572 CHECK_ALIVE(VisitForValue(expr->value())); | 3572 CHECK_ALIVE(VisitForValue(expr->value())); |
3573 value = Pop(); | 3573 value = Pop(); |
3574 HValue* object = Pop(); | 3574 HValue* object = Pop(); |
3575 | 3575 |
3576 Literal* key = prop->key()->AsLiteral(); | 3576 Literal* key = prop->key()->AsLiteral(); |
3577 Handle<String> name = Handle<String>::cast(key->handle()); | 3577 Handle<String> name = Handle<String>::cast(key->handle()); |
3578 ASSERT(!name.is_null()); | 3578 ASSERT(!name.is_null()); |
3579 | 3579 |
3580 SmallMapList* types = expr->GetReceiverTypes(); | 3580 SmallMapList* types = expr->GetReceiverTypes(); |
3581 LookupResult lookup; | 3581 LookupResult lookup(isolate()); |
3582 | 3582 |
3583 if (expr->IsMonomorphic()) { | 3583 if (expr->IsMonomorphic()) { |
3584 instr = BuildStoreNamed(object, value, expr); | 3584 instr = BuildStoreNamed(object, value, expr); |
3585 | 3585 |
3586 } else if (types != NULL && types->length() > 1) { | 3586 } else if (types != NULL && types->length() > 1) { |
3587 HandlePolymorphicStoreNamedField(expr, object, value, types, name); | 3587 HandlePolymorphicStoreNamedField(expr, object, value, types, name); |
3588 return; | 3588 return; |
3589 | 3589 |
3590 } else { | 3590 } else { |
3591 instr = BuildStoreNamedGeneric(object, name, value); | 3591 instr = BuildStoreNamedGeneric(object, name, value); |
(...skipping 24 matching lines...) Expand all Loading... |
3616 } | 3616 } |
3617 | 3617 |
3618 | 3618 |
3619 // Because not every expression has a position and there is not common | 3619 // Because not every expression has a position and there is not common |
3620 // superclass of Assignment and CountOperation, we cannot just pass the | 3620 // superclass of Assignment and CountOperation, we cannot just pass the |
3621 // owning expression instead of position and ast_id separately. | 3621 // owning expression instead of position and ast_id separately. |
3622 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, | 3622 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, |
3623 HValue* value, | 3623 HValue* value, |
3624 int position, | 3624 int position, |
3625 int ast_id) { | 3625 int ast_id) { |
3626 LookupResult lookup; | 3626 LookupResult lookup(isolate()); |
3627 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 3627 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
3628 if (type == kUseCell) { | 3628 if (type == kUseCell) { |
3629 Handle<GlobalObject> global(info()->global_object()); | 3629 Handle<GlobalObject> global(info()->global_object()); |
3630 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 3630 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
3631 HInstruction* instr = | 3631 HInstruction* instr = |
3632 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); | 3632 new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); |
3633 instr->set_position(position); | 3633 instr->set_position(position); |
3634 AddInstruction(instr); | 3634 AddInstruction(instr); |
3635 if (instr->HasSideEffects()) AddSimulate(ast_id); | 3635 if (instr->HasSideEffects()) AddSimulate(ast_id); |
3636 } else { | 3636 } else { |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3931 Handle<Object> name = expr->key()->AsLiteral()->handle(); | 3931 Handle<Object> name = expr->key()->AsLiteral()->handle(); |
3932 HValue* context = environment()->LookupContext(); | 3932 HValue* context = environment()->LookupContext(); |
3933 return new(zone()) HLoadNamedGeneric(context, obj, name); | 3933 return new(zone()) HLoadNamedGeneric(context, obj, name); |
3934 } | 3934 } |
3935 | 3935 |
3936 | 3936 |
3937 HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj, | 3937 HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj, |
3938 Property* expr, | 3938 Property* expr, |
3939 Handle<Map> map, | 3939 Handle<Map> map, |
3940 Handle<String> name) { | 3940 Handle<String> name) { |
3941 LookupResult lookup; | 3941 LookupResult lookup(isolate()); |
3942 map->LookupInDescriptors(NULL, *name, &lookup); | 3942 map->LookupInDescriptors(NULL, *name, &lookup); |
3943 if (lookup.IsProperty() && lookup.type() == FIELD) { | 3943 if (lookup.IsProperty() && lookup.type() == FIELD) { |
3944 return BuildLoadNamedField(obj, | 3944 return BuildLoadNamedField(obj, |
3945 expr, | 3945 expr, |
3946 map, | 3946 map, |
3947 &lookup, | 3947 &lookup, |
3948 true); | 3948 true); |
3949 } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) { | 3949 } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) { |
3950 AddInstruction(new(zone()) HCheckNonSmi(obj)); | 3950 AddInstruction(new(zone()) HCheckNonSmi(obj)); |
3951 AddInstruction(new(zone()) HCheckMap(obj, map)); | 3951 AddInstruction(new(zone()) HCheckMap(obj, map)); |
(...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5005 expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION); | 5005 expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION); |
5006 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 5006 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
5007 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); | 5007 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); |
5008 | 5008 |
5009 if (global_call) { | 5009 if (global_call) { |
5010 Variable* var = proxy->var(); | 5010 Variable* var = proxy->var(); |
5011 bool known_global_function = false; | 5011 bool known_global_function = false; |
5012 // If there is a global property cell for the name at compile time and | 5012 // If there is a global property cell for the name at compile time and |
5013 // access check is not enabled we assume that the function will not change | 5013 // access check is not enabled we assume that the function will not change |
5014 // and generate optimized code for calling the function. | 5014 // and generate optimized code for calling the function. |
5015 LookupResult lookup; | 5015 LookupResult lookup(isolate()); |
5016 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); | 5016 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); |
5017 if (type == kUseCell && | 5017 if (type == kUseCell && |
5018 !info()->global_object()->IsAccessCheckNeeded()) { | 5018 !info()->global_object()->IsAccessCheckNeeded()) { |
5019 Handle<GlobalObject> global(info()->global_object()); | 5019 Handle<GlobalObject> global(info()->global_object()); |
5020 known_global_function = expr->ComputeGlobalTarget(global, &lookup); | 5020 known_global_function = expr->ComputeGlobalTarget(global, &lookup); |
5021 } | 5021 } |
5022 if (known_global_function) { | 5022 if (known_global_function) { |
5023 // Push the global object instead of the global receiver because | 5023 // Push the global object instead of the global receiver because |
5024 // code generated by the full code generator expects it. | 5024 // code generated by the full code generator expects it. |
5025 HValue* context = environment()->LookupContext(); | 5025 HValue* context = environment()->LookupContext(); |
(...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5862 // residing in new space. If it is we assume that the function will stay the | 5862 // residing in new space. If it is we assume that the function will stay the |
5863 // same. | 5863 // same. |
5864 Handle<JSFunction> target = Handle<JSFunction>::null(); | 5864 Handle<JSFunction> target = Handle<JSFunction>::null(); |
5865 VariableProxy* proxy = expr->right()->AsVariableProxy(); | 5865 VariableProxy* proxy = expr->right()->AsVariableProxy(); |
5866 bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); | 5866 bool global_function = (proxy != NULL) && proxy->var()->IsUnallocated(); |
5867 if (global_function && | 5867 if (global_function && |
5868 info()->has_global_object() && | 5868 info()->has_global_object() && |
5869 !info()->global_object()->IsAccessCheckNeeded()) { | 5869 !info()->global_object()->IsAccessCheckNeeded()) { |
5870 Handle<String> name = proxy->name(); | 5870 Handle<String> name = proxy->name(); |
5871 Handle<GlobalObject> global(info()->global_object()); | 5871 Handle<GlobalObject> global(info()->global_object()); |
5872 LookupResult lookup; | 5872 LookupResult lookup(isolate()); |
5873 global->Lookup(*name, &lookup); | 5873 global->Lookup(*name, &lookup); |
5874 if (lookup.IsProperty() && | 5874 if (lookup.IsProperty() && |
5875 lookup.type() == NORMAL && | 5875 lookup.type() == NORMAL && |
5876 lookup.GetValue()->IsJSFunction()) { | 5876 lookup.GetValue()->IsJSFunction()) { |
5877 Handle<JSFunction> candidate(JSFunction::cast(lookup.GetValue())); | 5877 Handle<JSFunction> candidate(JSFunction::cast(lookup.GetValue())); |
5878 // If the function is in new space we assume it's more likely to | 5878 // If the function is in new space we assume it's more likely to |
5879 // change and thus prefer the general IC code. | 5879 // change and thus prefer the general IC code. |
5880 if (!isolate()->heap()->InNewSpace(*candidate)) { | 5880 if (!isolate()->heap()->InNewSpace(*candidate)) { |
5881 target = candidate; | 5881 target = candidate; |
5882 } | 5882 } |
(...skipping 1054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6937 } | 6937 } |
6938 } | 6938 } |
6939 | 6939 |
6940 #ifdef DEBUG | 6940 #ifdef DEBUG |
6941 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 6941 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
6942 if (allocator_ != NULL) allocator_->Verify(); | 6942 if (allocator_ != NULL) allocator_->Verify(); |
6943 #endif | 6943 #endif |
6944 } | 6944 } |
6945 | 6945 |
6946 } } // namespace v8::internal | 6946 } } // namespace v8::internal |
OLD | NEW |