| 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 |