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 2211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2222 // We don't yet handle the function name for named function expressions. | 2222 // We don't yet handle the function name for named function expressions. |
2223 if (scope->function() != NULL) return Bailout("named function expression"); | 2223 if (scope->function() != NULL) return Bailout("named function expression"); |
2224 | 2224 |
2225 HConstant* undefined_constant = new(zone()) HConstant( | 2225 HConstant* undefined_constant = new(zone()) HConstant( |
2226 isolate()->factory()->undefined_value(), Representation::Tagged()); | 2226 isolate()->factory()->undefined_value(), Representation::Tagged()); |
2227 AddInstruction(undefined_constant); | 2227 AddInstruction(undefined_constant); |
2228 graph_->set_undefined_constant(undefined_constant); | 2228 graph_->set_undefined_constant(undefined_constant); |
2229 | 2229 |
2230 // Set the initial values of parameters including "this". "This" has | 2230 // Set the initial values of parameters including "this". "This" has |
2231 // parameter index 0. | 2231 // parameter index 0. |
2232 int count = scope->num_parameters() + 1; | 2232 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); |
2233 for (int i = 0; i < count; ++i) { | 2233 |
| 2234 for (int i = 0; i < environment()->parameter_count(); ++i) { |
2234 HInstruction* parameter = AddInstruction(new(zone()) HParameter(i)); | 2235 HInstruction* parameter = AddInstruction(new(zone()) HParameter(i)); |
2235 environment()->Bind(i, parameter); | 2236 environment()->Bind(i, parameter); |
2236 } | 2237 } |
2237 | 2238 |
2238 // Set the initial values of stack-allocated locals. | 2239 // First special is HContext. |
2239 for (int i = count; i < environment()->length(); ++i) { | 2240 HInstruction* context = AddInstruction(new(zone()) HContext); |
| 2241 environment()->BindContext(context); |
| 2242 |
| 2243 // Initialize specials and locals to undefined. |
| 2244 for (int i = environment()->parameter_count() + 1; |
| 2245 i < environment()->length(); |
| 2246 ++i) { |
2240 environment()->Bind(i, undefined_constant); | 2247 environment()->Bind(i, undefined_constant); |
2241 } | 2248 } |
2242 | 2249 |
2243 // Handle the arguments and arguments shadow variables specially (they do | 2250 // Handle the arguments and arguments shadow variables specially (they do |
2244 // not have declarations). | 2251 // not have declarations). |
2245 if (scope->arguments() != NULL) { | 2252 if (scope->arguments() != NULL) { |
2246 if (!scope->arguments()->IsStackAllocated() || | 2253 if (!scope->arguments()->IsStackAllocated() || |
2247 (scope->arguments_shadow() != NULL && | 2254 (scope->arguments_shadow() != NULL && |
2248 !scope->arguments_shadow()->IsStackAllocated())) { | 2255 !scope->arguments_shadow()->IsStackAllocated())) { |
2249 return Bailout("context-allocated arguments"); | 2256 return Bailout("context-allocated arguments"); |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2586 HTest* test = new(zone()) HTest(true_value, non_osr_entry, osr_entry); | 2593 HTest* test = new(zone()) HTest(true_value, non_osr_entry, osr_entry); |
2587 current_block()->Finish(test); | 2594 current_block()->Finish(test); |
2588 | 2595 |
2589 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); | 2596 HBasicBlock* loop_predecessor = graph()->CreateBasicBlock(); |
2590 non_osr_entry->Goto(loop_predecessor); | 2597 non_osr_entry->Goto(loop_predecessor); |
2591 | 2598 |
2592 set_current_block(osr_entry); | 2599 set_current_block(osr_entry); |
2593 int osr_entry_id = statement->OsrEntryId(); | 2600 int osr_entry_id = statement->OsrEntryId(); |
2594 // We want the correct environment at the OsrEntry instruction. Build | 2601 // We want the correct environment at the OsrEntry instruction. Build |
2595 // it explicitly. The expression stack should be empty. | 2602 // it explicitly. The expression stack should be empty. |
2596 int count = environment()->length(); | 2603 ASSERT(environment()->ExpressionStackIsEmpty()); |
2597 ASSERT(count == | 2604 for (int i = 0; i < environment()->length(); ++i) { |
2598 (environment()->parameter_count() + environment()->local_count())); | 2605 HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue; |
2599 for (int i = 0; i < count; ++i) { | 2606 AddInstruction(osr_value); |
2600 HUnknownOSRValue* unknown = new(zone()) HUnknownOSRValue; | 2607 environment()->Bind(i, osr_value); |
2601 AddInstruction(unknown); | |
2602 environment()->Bind(i, unknown); | |
2603 } | 2608 } |
2604 | 2609 |
2605 AddSimulate(osr_entry_id); | 2610 AddSimulate(osr_entry_id); |
2606 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); | 2611 AddInstruction(new(zone()) HOsrEntry(osr_entry_id)); |
| 2612 HContext* context = new(zone()) HContext; |
| 2613 AddInstruction(context); |
| 2614 environment()->BindContext(context); |
2607 current_block()->Goto(loop_predecessor); | 2615 current_block()->Goto(loop_predecessor); |
2608 loop_predecessor->SetJoinId(statement->EntryId()); | 2616 loop_predecessor->SetJoinId(statement->EntryId()); |
2609 set_current_block(loop_predecessor); | 2617 set_current_block(loop_predecessor); |
2610 } | 2618 } |
2611 | 2619 |
2612 | 2620 |
2613 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { | 2621 void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { |
2614 ASSERT(!HasStackOverflow()); | 2622 ASSERT(!HasStackOverflow()); |
2615 ASSERT(current_block() != NULL); | 2623 ASSERT(current_block() != NULL); |
2616 ASSERT(current_block()->HasPredecessor()); | 2624 ASSERT(current_block()->HasPredecessor()); |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2879 lookup->holder() != *global) { | 2887 lookup->holder() != *global) { |
2880 return kUseGeneric; | 2888 return kUseGeneric; |
2881 } | 2889 } |
2882 | 2890 |
2883 return kUseCell; | 2891 return kUseCell; |
2884 } | 2892 } |
2885 | 2893 |
2886 | 2894 |
2887 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) { | 2895 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) { |
2888 ASSERT(var->IsContextSlot()); | 2896 ASSERT(var->IsContextSlot()); |
2889 HInstruction* context = new(zone()) HContext; | 2897 HValue* context = environment()->LookupContext(); |
2890 AddInstruction(context); | |
2891 int length = info()->scope()->ContextChainLength(var->scope()); | 2898 int length = info()->scope()->ContextChainLength(var->scope()); |
2892 while (length-- > 0) { | 2899 while (length-- > 0) { |
2893 context = new(zone()) HOuterContext(context); | 2900 HInstruction* context_instruction = new(zone()) HOuterContext(context); |
2894 AddInstruction(context); | 2901 AddInstruction(context_instruction); |
| 2902 context = context_instruction; |
2895 } | 2903 } |
2896 return context; | 2904 return context; |
2897 } | 2905 } |
2898 | 2906 |
2899 | 2907 |
2900 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 2908 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
2901 ASSERT(!HasStackOverflow()); | 2909 ASSERT(!HasStackOverflow()); |
2902 ASSERT(current_block() != NULL); | 2910 ASSERT(current_block() != NULL); |
2903 ASSERT(current_block()->HasPredecessor()); | 2911 ASSERT(current_block()->HasPredecessor()); |
2904 Variable* variable = expr->AsVariable(); | 2912 Variable* variable = expr->AsVariable(); |
(...skipping 18 matching lines...) Expand all Loading... |
2923 type = kUseGeneric; | 2931 type = kUseGeneric; |
2924 } | 2932 } |
2925 | 2933 |
2926 if (type == kUseCell) { | 2934 if (type == kUseCell) { |
2927 Handle<GlobalObject> global(info()->global_object()); | 2935 Handle<GlobalObject> global(info()->global_object()); |
2928 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 2936 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
2929 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); | 2937 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); |
2930 HLoadGlobalCell* instr = new(zone()) HLoadGlobalCell(cell, check_hole); | 2938 HLoadGlobalCell* instr = new(zone()) HLoadGlobalCell(cell, check_hole); |
2931 ast_context()->ReturnInstruction(instr, expr->id()); | 2939 ast_context()->ReturnInstruction(instr, expr->id()); |
2932 } else { | 2940 } else { |
2933 HContext* context = new(zone()) HContext; | 2941 HValue* context = environment()->LookupContext(); |
2934 AddInstruction(context); | |
2935 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 2942 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
2936 AddInstruction(global_object); | 2943 AddInstruction(global_object); |
2937 HLoadGlobalGeneric* instr = | 2944 HLoadGlobalGeneric* instr = |
2938 new(zone()) HLoadGlobalGeneric(context, | 2945 new(zone()) HLoadGlobalGeneric(context, |
2939 global_object, | 2946 global_object, |
2940 variable->name(), | 2947 variable->name(), |
2941 ast_context()->is_for_typeof()); | 2948 ast_context()->is_for_typeof()); |
2942 instr->set_position(expr->position()); | 2949 instr->set_position(expr->position()); |
2943 ASSERT(instr->HasSideEffects()); | 2950 ASSERT(instr->HasSideEffects()); |
2944 ast_context()->ReturnInstruction(instr, expr->id()); | 2951 ast_context()->ReturnInstruction(instr, expr->id()); |
(...skipping 22 matching lines...) Expand all Loading... |
2967 expr->flags(), | 2974 expr->flags(), |
2968 expr->literal_index()); | 2975 expr->literal_index()); |
2969 ast_context()->ReturnInstruction(instr, expr->id()); | 2976 ast_context()->ReturnInstruction(instr, expr->id()); |
2970 } | 2977 } |
2971 | 2978 |
2972 | 2979 |
2973 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { | 2980 void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
2974 ASSERT(!HasStackOverflow()); | 2981 ASSERT(!HasStackOverflow()); |
2975 ASSERT(current_block() != NULL); | 2982 ASSERT(current_block() != NULL); |
2976 ASSERT(current_block()->HasPredecessor()); | 2983 ASSERT(current_block()->HasPredecessor()); |
2977 HContext* context = new(zone()) HContext; | 2984 HValue* context = environment()->LookupContext(); |
2978 AddInstruction(context); | |
2979 HObjectLiteral* literal = | 2985 HObjectLiteral* literal = |
2980 new(zone()) HObjectLiteral(context, | 2986 new(zone()) HObjectLiteral(context, |
2981 expr->constant_properties(), | 2987 expr->constant_properties(), |
2982 expr->fast_elements(), | 2988 expr->fast_elements(), |
2983 expr->literal_index(), | 2989 expr->literal_index(), |
2984 expr->depth(), | 2990 expr->depth(), |
2985 expr->has_function()); | 2991 expr->has_function()); |
2986 // The object is expected in the bailout environment during computation | 2992 // The object is expected in the bailout environment during computation |
2987 // of the property values and is the value of the entire expression. | 2993 // of the property values and is the value of the entire expression. |
2988 PushAndAdd(literal); | 2994 PushAndAdd(literal); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3150 // enable elimination of redundant checks after the transition store. | 3156 // enable elimination of redundant checks after the transition store. |
3151 instr->SetFlag(HValue::kChangesMaps); | 3157 instr->SetFlag(HValue::kChangesMaps); |
3152 } | 3158 } |
3153 return instr; | 3159 return instr; |
3154 } | 3160 } |
3155 | 3161 |
3156 | 3162 |
3157 HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object, | 3163 HInstruction* HGraphBuilder::BuildStoreNamedGeneric(HValue* object, |
3158 Handle<String> name, | 3164 Handle<String> name, |
3159 HValue* value) { | 3165 HValue* value) { |
3160 HContext* context = new(zone()) HContext; | 3166 HValue* context = environment()->LookupContext(); |
3161 AddInstruction(context); | |
3162 return new(zone()) HStoreNamedGeneric( | 3167 return new(zone()) HStoreNamedGeneric( |
3163 context, | 3168 context, |
3164 object, | 3169 object, |
3165 name, | 3170 name, |
3166 value, | 3171 value, |
3167 function_strict_mode()); | 3172 function_strict_mode()); |
3168 } | 3173 } |
3169 | 3174 |
3170 | 3175 |
3171 HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, | 3176 HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3327 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); | 3332 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
3328 if (type == kUseCell) { | 3333 if (type == kUseCell) { |
3329 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); | 3334 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); |
3330 Handle<GlobalObject> global(info()->global_object()); | 3335 Handle<GlobalObject> global(info()->global_object()); |
3331 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 3336 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
3332 HInstruction* instr = new(zone()) HStoreGlobalCell(value, cell, check_hole); | 3337 HInstruction* instr = new(zone()) HStoreGlobalCell(value, cell, check_hole); |
3333 instr->set_position(position); | 3338 instr->set_position(position); |
3334 AddInstruction(instr); | 3339 AddInstruction(instr); |
3335 if (instr->HasSideEffects()) AddSimulate(ast_id); | 3340 if (instr->HasSideEffects()) AddSimulate(ast_id); |
3336 } else { | 3341 } else { |
3337 HContext* context = new(zone()) HContext; | 3342 HValue* context = environment()->LookupContext(); |
3338 AddInstruction(context); | |
3339 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 3343 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
3340 AddInstruction(global_object); | 3344 AddInstruction(global_object); |
3341 HStoreGlobalGeneric* instr = | 3345 HStoreGlobalGeneric* instr = |
3342 new(zone()) HStoreGlobalGeneric(context, | 3346 new(zone()) HStoreGlobalGeneric(context, |
3343 global_object, | 3347 global_object, |
3344 var->name(), | 3348 var->name(), |
3345 value, | 3349 value, |
3346 function_strict_mode()); | 3350 function_strict_mode()); |
3347 instr->set_position(position); | 3351 instr->set_position(position); |
3348 AddInstruction(instr); | 3352 AddInstruction(instr); |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3553 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; | 3557 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; |
3554 return new(zone()) HLoadNamedField(object, false, offset); | 3558 return new(zone()) HLoadNamedField(object, false, offset); |
3555 } | 3559 } |
3556 } | 3560 } |
3557 | 3561 |
3558 | 3562 |
3559 HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj, | 3563 HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj, |
3560 Property* expr) { | 3564 Property* expr) { |
3561 ASSERT(expr->key()->IsPropertyName()); | 3565 ASSERT(expr->key()->IsPropertyName()); |
3562 Handle<Object> name = expr->key()->AsLiteral()->handle(); | 3566 Handle<Object> name = expr->key()->AsLiteral()->handle(); |
3563 HContext* context = new(zone()) HContext; | 3567 HValue* context = environment()->LookupContext(); |
3564 AddInstruction(context); | |
3565 return new(zone()) HLoadNamedGeneric(context, obj, name); | 3568 return new(zone()) HLoadNamedGeneric(context, obj, name); |
3566 } | 3569 } |
3567 | 3570 |
3568 | 3571 |
3569 HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj, | 3572 HInstruction* HGraphBuilder::BuildLoadNamed(HValue* obj, |
3570 Property* expr, | 3573 Property* expr, |
3571 Handle<Map> map, | 3574 Handle<Map> map, |
3572 Handle<String> name) { | 3575 Handle<String> name) { |
3573 LookupResult lookup; | 3576 LookupResult lookup; |
3574 map->LookupInDescriptors(NULL, *name, &lookup); | 3577 map->LookupInDescriptors(NULL, *name, &lookup); |
3575 if (lookup.IsProperty() && lookup.type() == FIELD) { | 3578 if (lookup.IsProperty() && lookup.type() == FIELD) { |
3576 return BuildLoadNamedField(obj, | 3579 return BuildLoadNamedField(obj, |
3577 expr, | 3580 expr, |
3578 map, | 3581 map, |
3579 &lookup, | 3582 &lookup, |
3580 true); | 3583 true); |
3581 } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) { | 3584 } else if (lookup.IsProperty() && lookup.type() == CONSTANT_FUNCTION) { |
3582 AddInstruction(new(zone()) HCheckNonSmi(obj)); | 3585 AddInstruction(new(zone()) HCheckNonSmi(obj)); |
3583 AddInstruction(new(zone()) HCheckMap(obj, map)); | 3586 AddInstruction(new(zone()) HCheckMap(obj, map)); |
3584 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); | 3587 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); |
3585 return new(zone()) HConstant(function, Representation::Tagged()); | 3588 return new(zone()) HConstant(function, Representation::Tagged()); |
3586 } else { | 3589 } else { |
3587 return BuildLoadNamedGeneric(obj, expr); | 3590 return BuildLoadNamedGeneric(obj, expr); |
3588 } | 3591 } |
3589 } | 3592 } |
3590 | 3593 |
3591 | 3594 |
3592 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 3595 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
3593 HValue* key) { | 3596 HValue* key) { |
3594 HContext* context = new(zone()) HContext; | 3597 HValue* context = environment()->LookupContext(); |
3595 AddInstruction(context); | |
3596 return new(zone()) HLoadKeyedGeneric(context, object, key); | 3598 return new(zone()) HLoadKeyedGeneric(context, object, key); |
3597 } | 3599 } |
3598 | 3600 |
3599 | 3601 |
3600 HInstruction* HGraphBuilder::BuildLoadKeyedFastElement(HValue* object, | 3602 HInstruction* HGraphBuilder::BuildLoadKeyedFastElement(HValue* object, |
3601 HValue* key, | 3603 HValue* key, |
3602 Property* expr) { | 3604 Property* expr) { |
3603 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); | 3605 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); |
3604 AddInstruction(new(zone()) HCheckNonSmi(object)); | 3606 AddInstruction(new(zone()) HCheckNonSmi(object)); |
3605 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 3607 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3660 return BuildLoadKeyedFastElement(obj, key, prop); | 3662 return BuildLoadKeyedFastElement(obj, key, prop); |
3661 } | 3663 } |
3662 } | 3664 } |
3663 return BuildLoadKeyedGeneric(obj, key); | 3665 return BuildLoadKeyedGeneric(obj, key); |
3664 } | 3666 } |
3665 | 3667 |
3666 | 3668 |
3667 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, | 3669 HInstruction* HGraphBuilder::BuildStoreKeyedGeneric(HValue* object, |
3668 HValue* key, | 3670 HValue* key, |
3669 HValue* value) { | 3671 HValue* value) { |
3670 HContext* context = new(zone()) HContext; | 3672 HValue* context = environment()->LookupContext(); |
3671 AddInstruction(context); | |
3672 return new(zone()) HStoreKeyedGeneric( | 3673 return new(zone()) HStoreKeyedGeneric( |
3673 context, | 3674 context, |
3674 object, | 3675 object, |
3675 key, | 3676 key, |
3676 value, | 3677 value, |
3677 function_strict_mode()); | 3678 function_strict_mode()); |
3678 } | 3679 } |
3679 | 3680 |
3680 | 3681 |
3681 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object, | 3682 HInstruction* HGraphBuilder::BuildStoreKeyedFastElement(HValue* object, |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3914 set_current_block(if_false); | 3915 set_current_block(if_false); |
3915 } | 3916 } |
3916 } | 3917 } |
3917 | 3918 |
3918 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 3919 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
3919 // know about and do not want to handle ones we've never seen. Otherwise | 3920 // know about and do not want to handle ones we've never seen. Otherwise |
3920 // use a generic IC. | 3921 // use a generic IC. |
3921 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { | 3922 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { |
3922 current_block()->FinishExitWithDeoptimization(); | 3923 current_block()->FinishExitWithDeoptimization(); |
3923 } else { | 3924 } else { |
3924 HContext* context = new(zone()) HContext; | 3925 HValue* context = environment()->LookupContext(); |
3925 AddInstruction(context); | |
3926 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); | 3926 HCallNamed* call = new(zone()) HCallNamed(context, name, argument_count); |
3927 call->set_position(expr->position()); | 3927 call->set_position(expr->position()); |
3928 PreProcessCall(call); | 3928 PreProcessCall(call); |
3929 | 3929 |
3930 if (join != NULL) { | 3930 if (join != NULL) { |
3931 AddInstruction(call); | 3931 AddInstruction(call); |
3932 if (!ast_context()->IsEffect()) Push(call); | 3932 if (!ast_context()->IsEffect()) Push(call); |
3933 current_block()->Goto(join); | 3933 current_block()->Goto(join); |
3934 } else { | 3934 } else { |
3935 ast_context()->ReturnInstruction(call, expr->id()); | 3935 ast_context()->ReturnInstruction(call, expr->id()); |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4342 | 4342 |
4343 CHECK_ALIVE(VisitForValue(prop->key())); | 4343 CHECK_ALIVE(VisitForValue(prop->key())); |
4344 // Push receiver and key like the non-optimized code generator expects it. | 4344 // Push receiver and key like the non-optimized code generator expects it. |
4345 HValue* key = Pop(); | 4345 HValue* key = Pop(); |
4346 HValue* receiver = Pop(); | 4346 HValue* receiver = Pop(); |
4347 Push(key); | 4347 Push(key); |
4348 Push(receiver); | 4348 Push(receiver); |
4349 | 4349 |
4350 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4350 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
4351 | 4351 |
4352 HContext* context = new(zone()) HContext; | 4352 HValue* context = environment()->LookupContext(); |
4353 AddInstruction(context); | |
4354 call = PreProcessCall( | 4353 call = PreProcessCall( |
4355 new(zone()) HCallKeyed(context, key, argument_count)); | 4354 new(zone()) HCallKeyed(context, key, argument_count)); |
4356 call->set_position(expr->position()); | 4355 call->set_position(expr->position()); |
4357 Drop(1); // Key. | 4356 Drop(1); // Key. |
4358 ast_context()->ReturnInstruction(call, expr->id()); | 4357 ast_context()->ReturnInstruction(call, expr->id()); |
4359 return; | 4358 return; |
4360 } | 4359 } |
4361 | 4360 |
4362 // Named function call. | 4361 // Named function call. |
4363 expr->RecordTypeFeedback(oracle()); | 4362 expr->RecordTypeFeedback(oracle()); |
(...skipping 18 matching lines...) Expand all Loading... |
4382 receiver_map, | 4381 receiver_map, |
4383 expr->check_type())) { | 4382 expr->check_type())) { |
4384 return; | 4383 return; |
4385 } | 4384 } |
4386 | 4385 |
4387 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) || | 4386 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) || |
4388 expr->check_type() != RECEIVER_MAP_CHECK) { | 4387 expr->check_type() != RECEIVER_MAP_CHECK) { |
4389 // When the target has a custom call IC generator, use the IC, | 4388 // When the target has a custom call IC generator, use the IC, |
4390 // because it is likely to generate better code. Also use the IC | 4389 // because it is likely to generate better code. Also use the IC |
4391 // when a primitive receiver check is required. | 4390 // when a primitive receiver check is required. |
4392 HContext* context = new(zone()) HContext; | 4391 HValue* context = environment()->LookupContext(); |
4393 AddInstruction(context); | |
4394 call = PreProcessCall( | 4392 call = PreProcessCall( |
4395 new(zone()) HCallNamed(context, name, argument_count)); | 4393 new(zone()) HCallNamed(context, name, argument_count)); |
4396 } else { | 4394 } else { |
4397 AddCheckConstantFunction(expr, receiver, receiver_map, true); | 4395 AddCheckConstantFunction(expr, receiver, receiver_map, true); |
4398 | 4396 |
4399 if (TryInline(expr)) return; | 4397 if (TryInline(expr)) return; |
4400 call = PreProcessCall( | 4398 call = PreProcessCall( |
4401 new(zone()) HCallConstantFunction(expr->target(), | 4399 new(zone()) HCallConstantFunction(expr->target(), |
4402 argument_count)); | 4400 argument_count)); |
4403 } | 4401 } |
4404 } else if (types != NULL && types->length() > 1) { | 4402 } else if (types != NULL && types->length() > 1) { |
4405 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); | 4403 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); |
4406 HandlePolymorphicCallNamed(expr, receiver, types, name); | 4404 HandlePolymorphicCallNamed(expr, receiver, types, name); |
4407 return; | 4405 return; |
4408 | 4406 |
4409 } else { | 4407 } else { |
4410 HContext* context = new(zone()) HContext; | 4408 HValue* context = environment()->LookupContext(); |
4411 AddInstruction(context); | |
4412 call = PreProcessCall( | 4409 call = PreProcessCall( |
4413 new(zone()) HCallNamed(context, name, argument_count)); | 4410 new(zone()) HCallNamed(context, name, argument_count)); |
4414 } | 4411 } |
4415 | 4412 |
4416 } else { | 4413 } else { |
4417 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); | 4414 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
4418 bool global_call = (var != NULL) && var->is_global() && !var->is_this(); | 4415 bool global_call = (var != NULL) && var->is_global() && !var->is_this(); |
4419 | 4416 |
4420 if (!global_call) { | 4417 if (!global_call) { |
4421 ++argument_count; | 4418 ++argument_count; |
4422 CHECK_ALIVE(VisitForValue(expr->expression())); | 4419 CHECK_ALIVE(VisitForValue(expr->expression())); |
4423 } | 4420 } |
4424 | 4421 |
4425 if (global_call) { | 4422 if (global_call) { |
4426 bool known_global_function = false; | 4423 bool known_global_function = false; |
4427 // If there is a global property cell for the name at compile time and | 4424 // If there is a global property cell for the name at compile time and |
4428 // access check is not enabled we assume that the function will not change | 4425 // access check is not enabled we assume that the function will not change |
4429 // and generate optimized code for calling the function. | 4426 // and generate optimized code for calling the function. |
4430 LookupResult lookup; | 4427 LookupResult lookup; |
4431 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); | 4428 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); |
4432 if (type == kUseCell && | 4429 if (type == kUseCell && |
4433 !info()->global_object()->IsAccessCheckNeeded()) { | 4430 !info()->global_object()->IsAccessCheckNeeded()) { |
4434 Handle<GlobalObject> global(info()->global_object()); | 4431 Handle<GlobalObject> global(info()->global_object()); |
4435 known_global_function = expr->ComputeGlobalTarget(global, &lookup); | 4432 known_global_function = expr->ComputeGlobalTarget(global, &lookup); |
4436 } | 4433 } |
4437 if (known_global_function) { | 4434 if (known_global_function) { |
4438 // Push the global object instead of the global receiver because | 4435 // Push the global object instead of the global receiver because |
4439 // code generated by the full code generator expects it. | 4436 // code generated by the full code generator expects it. |
4440 HContext* context = new(zone()) HContext; | 4437 HValue* context = environment()->LookupContext(); |
4441 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 4438 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
4442 AddInstruction(context); | |
4443 PushAndAdd(global_object); | 4439 PushAndAdd(global_object); |
4444 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4440 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
4445 | 4441 |
4446 CHECK_ALIVE(VisitForValue(expr->expression())); | 4442 CHECK_ALIVE(VisitForValue(expr->expression())); |
4447 HValue* function = Pop(); | 4443 HValue* function = Pop(); |
4448 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); | 4444 AddInstruction(new(zone()) HCheckFunction(function, expr->target())); |
4449 | 4445 |
4450 // Replace the global object with the global receiver. | 4446 // Replace the global object with the global receiver. |
4451 HGlobalReceiver* global_receiver = | 4447 HGlobalReceiver* global_receiver = |
4452 new(zone()) HGlobalReceiver(global_object); | 4448 new(zone()) HGlobalReceiver(global_object); |
4453 // Index of the receiver from the top of the expression stack. | 4449 // Index of the receiver from the top of the expression stack. |
4454 const int receiver_index = argument_count - 1; | 4450 const int receiver_index = argument_count - 1; |
4455 AddInstruction(global_receiver); | 4451 AddInstruction(global_receiver); |
4456 ASSERT(environment()->ExpressionStackAt(receiver_index)-> | 4452 ASSERT(environment()->ExpressionStackAt(receiver_index)-> |
4457 IsGlobalObject()); | 4453 IsGlobalObject()); |
4458 environment()->SetExpressionStackAt(receiver_index, global_receiver); | 4454 environment()->SetExpressionStackAt(receiver_index, global_receiver); |
4459 | 4455 |
4460 if (TryInline(expr)) return; | 4456 if (TryInline(expr)) return; |
4461 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), | 4457 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), |
4462 argument_count)); | 4458 argument_count)); |
4463 } else { | 4459 } else { |
4464 HContext* context = new(zone()) HContext; | 4460 HValue* context = environment()->LookupContext(); |
4465 AddInstruction(context); | |
4466 PushAndAdd(new(zone()) HGlobalObject(context)); | 4461 PushAndAdd(new(zone()) HGlobalObject(context)); |
4467 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4462 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
4468 | 4463 |
4469 call = PreProcessCall(new(zone()) HCallGlobal(context, | 4464 call = PreProcessCall(new(zone()) HCallGlobal(context, |
4470 var->name(), | 4465 var->name(), |
4471 argument_count)); | 4466 argument_count)); |
4472 } | 4467 } |
4473 | 4468 |
4474 } else { | 4469 } else { |
4475 HContext* context = new(zone()) HContext; | 4470 HValue* context = environment()->LookupContext(); |
4476 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | 4471 HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
4477 AddInstruction(context); | |
4478 AddInstruction(global_object); | 4472 AddInstruction(global_object); |
4479 PushAndAdd(new(zone()) HGlobalReceiver(global_object)); | 4473 PushAndAdd(new(zone()) HGlobalReceiver(global_object)); |
4480 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4474 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
4481 | 4475 |
4482 call = PreProcessCall(new(zone()) HCallFunction(context, argument_count)); | 4476 call = PreProcessCall(new(zone()) HCallFunction(context, argument_count)); |
4483 } | 4477 } |
4484 } | 4478 } |
4485 | 4479 |
4486 call->set_position(expr->position()); | 4480 call->set_position(expr->position()); |
4487 ast_context()->ReturnInstruction(call, expr->id()); | 4481 ast_context()->ReturnInstruction(call, expr->id()); |
4488 } | 4482 } |
4489 | 4483 |
4490 | 4484 |
4491 void HGraphBuilder::VisitCallNew(CallNew* expr) { | 4485 void HGraphBuilder::VisitCallNew(CallNew* expr) { |
4492 ASSERT(!HasStackOverflow()); | 4486 ASSERT(!HasStackOverflow()); |
4493 ASSERT(current_block() != NULL); | 4487 ASSERT(current_block() != NULL); |
4494 ASSERT(current_block()->HasPredecessor()); | 4488 ASSERT(current_block()->HasPredecessor()); |
4495 // The constructor function is also used as the receiver argument to the | 4489 // The constructor function is also used as the receiver argument to the |
4496 // JS construct call builtin. | 4490 // JS construct call builtin. |
4497 CHECK_ALIVE(VisitForValue(expr->expression())); | 4491 CHECK_ALIVE(VisitForValue(expr->expression())); |
4498 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 4492 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
4499 | 4493 |
4500 HContext* context = new(zone()) HContext; | 4494 HValue* context = environment()->LookupContext(); |
4501 AddInstruction(context); | |
4502 | 4495 |
4503 // The constructor is both an operand to the instruction and an argument | 4496 // The constructor is both an operand to the instruction and an argument |
4504 // to the construct call. | 4497 // to the construct call. |
4505 int arg_count = expr->arguments()->length() + 1; // Plus constructor. | 4498 int arg_count = expr->arguments()->length() + 1; // Plus constructor. |
4506 HValue* constructor = environment()->ExpressionStackAt(arg_count - 1); | 4499 HValue* constructor = environment()->ExpressionStackAt(arg_count - 1); |
4507 HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count); | 4500 HCallNew* call = new(zone()) HCallNew(context, constructor, arg_count); |
4508 call->set_position(expr->position()); | 4501 call->set_position(expr->position()); |
4509 PreProcessCall(call); | 4502 PreProcessCall(call); |
4510 ast_context()->ReturnInstruction(call, expr->id()); | 4503 ast_context()->ReturnInstruction(call, expr->id()); |
4511 } | 4504 } |
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5114 // change and thus prefer the general IC code. | 5107 // change and thus prefer the general IC code. |
5115 if (!isolate()->heap()->InNewSpace(*candidate)) { | 5108 if (!isolate()->heap()->InNewSpace(*candidate)) { |
5116 target = candidate; | 5109 target = candidate; |
5117 } | 5110 } |
5118 } | 5111 } |
5119 } | 5112 } |
5120 | 5113 |
5121 // If the target is not null we have found a known global function that is | 5114 // If the target is not null we have found a known global function that is |
5122 // assumed to stay the same for this instanceof. | 5115 // assumed to stay the same for this instanceof. |
5123 if (target.is_null()) { | 5116 if (target.is_null()) { |
5124 HContext* context = new(zone()) HContext; | 5117 HValue* context = environment()->LookupContext(); |
5125 AddInstruction(context); | |
5126 instr = new(zone()) HInstanceOf(context, left, right); | 5118 instr = new(zone()) HInstanceOf(context, left, right); |
5127 } else { | 5119 } else { |
5128 AddInstruction(new(zone()) HCheckFunction(right, target)); | 5120 AddInstruction(new(zone()) HCheckFunction(right, target)); |
5129 instr = new(zone()) HInstanceOfKnownGlobal(left, target); | 5121 instr = new(zone()) HInstanceOfKnownGlobal(left, target); |
5130 } | 5122 } |
5131 } else if (op == Token::IN) { | 5123 } else if (op == Token::IN) { |
5132 instr = new(zone()) HIn(left, right); | 5124 instr = new(zone()) HIn(left, right); |
5133 } else if (type_info.IsNonPrimitive()) { | 5125 } else if (type_info.IsNonPrimitive()) { |
5134 switch (op) { | 5126 switch (op) { |
5135 case Token::EQ: | 5127 case Token::EQ: |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5391 // Fast support for Math.random(). | 5383 // Fast support for Math.random(). |
5392 void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { | 5384 void HGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { |
5393 return Bailout("inlined runtime function: RandomHeapNumber"); | 5385 return Bailout("inlined runtime function: RandomHeapNumber"); |
5394 } | 5386 } |
5395 | 5387 |
5396 | 5388 |
5397 // Fast support for StringAdd. | 5389 // Fast support for StringAdd. |
5398 void HGraphBuilder::GenerateStringAdd(CallRuntime* call) { | 5390 void HGraphBuilder::GenerateStringAdd(CallRuntime* call) { |
5399 ASSERT_EQ(2, call->arguments()->length()); | 5391 ASSERT_EQ(2, call->arguments()->length()); |
5400 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5392 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5401 HContext* context = new(zone()) HContext; | 5393 HValue* context = environment()->LookupContext(); |
5402 AddInstruction(context); | |
5403 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2); | 5394 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2); |
5404 Drop(2); | 5395 Drop(2); |
5405 ast_context()->ReturnInstruction(result, call->id()); | 5396 ast_context()->ReturnInstruction(result, call->id()); |
5406 } | 5397 } |
5407 | 5398 |
5408 | 5399 |
5409 // Fast support for SubString. | 5400 // Fast support for SubString. |
5410 void HGraphBuilder::GenerateSubString(CallRuntime* call) { | 5401 void HGraphBuilder::GenerateSubString(CallRuntime* call) { |
5411 ASSERT_EQ(3, call->arguments()->length()); | 5402 ASSERT_EQ(3, call->arguments()->length()); |
5412 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5403 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5413 HContext* context = new(zone()) HContext; | 5404 HValue* context = environment()->LookupContext(); |
5414 AddInstruction(context); | |
5415 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3); | 5405 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3); |
5416 Drop(3); | 5406 Drop(3); |
5417 ast_context()->ReturnInstruction(result, call->id()); | 5407 ast_context()->ReturnInstruction(result, call->id()); |
5418 } | 5408 } |
5419 | 5409 |
5420 | 5410 |
5421 // Fast support for StringCompare. | 5411 // Fast support for StringCompare. |
5422 void HGraphBuilder::GenerateStringCompare(CallRuntime* call) { | 5412 void HGraphBuilder::GenerateStringCompare(CallRuntime* call) { |
5423 ASSERT_EQ(2, call->arguments()->length()); | 5413 ASSERT_EQ(2, call->arguments()->length()); |
5424 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5414 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5425 HContext* context = new(zone()) HContext; | 5415 HValue* context = environment()->LookupContext(); |
5426 AddInstruction(context); | |
5427 HCallStub* result = | 5416 HCallStub* result = |
5428 new(zone()) HCallStub(context, CodeStub::StringCompare, 2); | 5417 new(zone()) HCallStub(context, CodeStub::StringCompare, 2); |
5429 Drop(2); | 5418 Drop(2); |
5430 ast_context()->ReturnInstruction(result, call->id()); | 5419 ast_context()->ReturnInstruction(result, call->id()); |
5431 } | 5420 } |
5432 | 5421 |
5433 | 5422 |
5434 // Support for direct calls from JavaScript to native RegExp code. | 5423 // Support for direct calls from JavaScript to native RegExp code. |
5435 void HGraphBuilder::GenerateRegExpExec(CallRuntime* call) { | 5424 void HGraphBuilder::GenerateRegExpExec(CallRuntime* call) { |
5436 ASSERT_EQ(4, call->arguments()->length()); | 5425 ASSERT_EQ(4, call->arguments()->length()); |
5437 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5426 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5438 HContext* context = new(zone()) HContext; | 5427 HValue* context = environment()->LookupContext(); |
5439 AddInstruction(context); | |
5440 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4); | 5428 HCallStub* result = new(zone()) HCallStub(context, CodeStub::RegExpExec, 4); |
5441 Drop(4); | 5429 Drop(4); |
5442 ast_context()->ReturnInstruction(result, call->id()); | 5430 ast_context()->ReturnInstruction(result, call->id()); |
5443 } | 5431 } |
5444 | 5432 |
5445 | 5433 |
5446 // Construct a RegExp exec result with two in-object properties. | 5434 // Construct a RegExp exec result with two in-object properties. |
5447 void HGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { | 5435 void HGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { |
5448 ASSERT_EQ(3, call->arguments()->length()); | 5436 ASSERT_EQ(3, call->arguments()->length()); |
5449 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5437 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5450 HContext* context = new(zone()) HContext; | 5438 HValue* context = environment()->LookupContext(); |
5451 AddInstruction(context); | |
5452 HCallStub* result = | 5439 HCallStub* result = |
5453 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3); | 5440 new(zone()) HCallStub(context, CodeStub::RegExpConstructResult, 3); |
5454 Drop(3); | 5441 Drop(3); |
5455 ast_context()->ReturnInstruction(result, call->id()); | 5442 ast_context()->ReturnInstruction(result, call->id()); |
5456 } | 5443 } |
5457 | 5444 |
5458 | 5445 |
5459 // Support for fast native caches. | 5446 // Support for fast native caches. |
5460 void HGraphBuilder::GenerateGetFromCache(CallRuntime* call) { | 5447 void HGraphBuilder::GenerateGetFromCache(CallRuntime* call) { |
5461 return Bailout("inlined runtime function: GetFromCache"); | 5448 return Bailout("inlined runtime function: GetFromCache"); |
5462 } | 5449 } |
5463 | 5450 |
5464 | 5451 |
5465 // Fast support for number to string. | 5452 // Fast support for number to string. |
5466 void HGraphBuilder::GenerateNumberToString(CallRuntime* call) { | 5453 void HGraphBuilder::GenerateNumberToString(CallRuntime* call) { |
5467 ASSERT_EQ(1, call->arguments()->length()); | 5454 ASSERT_EQ(1, call->arguments()->length()); |
5468 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5455 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5469 HContext* context = new(zone()) HContext; | 5456 HValue* context = environment()->LookupContext(); |
5470 AddInstruction(context); | |
5471 HCallStub* result = | 5457 HCallStub* result = |
5472 new(zone()) HCallStub(context, CodeStub::NumberToString, 1); | 5458 new(zone()) HCallStub(context, CodeStub::NumberToString, 1); |
5473 Drop(1); | 5459 Drop(1); |
5474 ast_context()->ReturnInstruction(result, call->id()); | 5460 ast_context()->ReturnInstruction(result, call->id()); |
5475 } | 5461 } |
5476 | 5462 |
5477 | 5463 |
5478 // Fast swapping of elements. Takes three expressions, the object and two | 5464 // Fast swapping of elements. Takes three expressions, the object and two |
5479 // indices. This should only be used if the indices are known to be | 5465 // indices. This should only be used if the indices are known to be |
5480 // non-negative and within bounds of the elements array at the call site. | 5466 // non-negative and within bounds of the elements array at the call site. |
5481 void HGraphBuilder::GenerateSwapElements(CallRuntime* call) { | 5467 void HGraphBuilder::GenerateSwapElements(CallRuntime* call) { |
5482 return Bailout("inlined runtime function: SwapElements"); | 5468 return Bailout("inlined runtime function: SwapElements"); |
5483 } | 5469 } |
5484 | 5470 |
5485 | 5471 |
5486 // Fast call for custom callbacks. | 5472 // Fast call for custom callbacks. |
5487 void HGraphBuilder::GenerateCallFunction(CallRuntime* call) { | 5473 void HGraphBuilder::GenerateCallFunction(CallRuntime* call) { |
5488 // 1 ~ The function to call is not itself an argument to the call. | 5474 // 1 ~ The function to call is not itself an argument to the call. |
5489 int arg_count = call->arguments()->length() - 1; | 5475 int arg_count = call->arguments()->length() - 1; |
5490 ASSERT(arg_count >= 1); // There's always at least a receiver. | 5476 ASSERT(arg_count >= 1); // There's always at least a receiver. |
5491 | 5477 |
5492 for (int i = 0; i < arg_count; ++i) { | 5478 for (int i = 0; i < arg_count; ++i) { |
5493 CHECK_ALIVE(VisitArgument(call->arguments()->at(i))); | 5479 CHECK_ALIVE(VisitArgument(call->arguments()->at(i))); |
5494 } | 5480 } |
5495 CHECK_ALIVE(VisitForValue(call->arguments()->last())); | 5481 CHECK_ALIVE(VisitForValue(call->arguments()->last())); |
5496 HValue* function = Pop(); | 5482 HValue* function = Pop(); |
5497 HContext* context = new HContext; | 5483 HValue* context = environment()->LookupContext(); |
5498 AddInstruction(context); | |
5499 HInvokeFunction* result = | 5484 HInvokeFunction* result = |
5500 new(zone()) HInvokeFunction(context, function, arg_count); | 5485 new(zone()) HInvokeFunction(context, function, arg_count); |
5501 Drop(arg_count); | 5486 Drop(arg_count); |
5502 ast_context()->ReturnInstruction(result, call->id()); | 5487 ast_context()->ReturnInstruction(result, call->id()); |
5503 } | 5488 } |
5504 | 5489 |
5505 | 5490 |
5506 // Fast call to math functions. | 5491 // Fast call to math functions. |
5507 void HGraphBuilder::GenerateMathPow(CallRuntime* call) { | 5492 void HGraphBuilder::GenerateMathPow(CallRuntime* call) { |
5508 ASSERT_EQ(2, call->arguments()->length()); | 5493 ASSERT_EQ(2, call->arguments()->length()); |
5509 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 5494 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
5510 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 5495 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
5511 HValue* right = Pop(); | 5496 HValue* right = Pop(); |
5512 HValue* left = Pop(); | 5497 HValue* left = Pop(); |
5513 HPower* result = new(zone()) HPower(left, right); | 5498 HPower* result = new(zone()) HPower(left, right); |
5514 ast_context()->ReturnInstruction(result, call->id()); | 5499 ast_context()->ReturnInstruction(result, call->id()); |
5515 } | 5500 } |
5516 | 5501 |
5517 | 5502 |
5518 void HGraphBuilder::GenerateMathSin(CallRuntime* call) { | 5503 void HGraphBuilder::GenerateMathSin(CallRuntime* call) { |
5519 ASSERT_EQ(1, call->arguments()->length()); | 5504 ASSERT_EQ(1, call->arguments()->length()); |
5520 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5505 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5521 HContext* context = new(zone()) HContext; | 5506 HValue* context = environment()->LookupContext(); |
5522 AddInstruction(context); | |
5523 HCallStub* result = | 5507 HCallStub* result = |
5524 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); | 5508 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); |
5525 result->set_transcendental_type(TranscendentalCache::SIN); | 5509 result->set_transcendental_type(TranscendentalCache::SIN); |
5526 Drop(1); | 5510 Drop(1); |
5527 ast_context()->ReturnInstruction(result, call->id()); | 5511 ast_context()->ReturnInstruction(result, call->id()); |
5528 } | 5512 } |
5529 | 5513 |
5530 | 5514 |
5531 void HGraphBuilder::GenerateMathCos(CallRuntime* call) { | 5515 void HGraphBuilder::GenerateMathCos(CallRuntime* call) { |
5532 ASSERT_EQ(1, call->arguments()->length()); | 5516 ASSERT_EQ(1, call->arguments()->length()); |
5533 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5517 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5534 HContext* context = new(zone()) HContext; | 5518 HValue* context = environment()->LookupContext(); |
5535 AddInstruction(context); | |
5536 HCallStub* result = | 5519 HCallStub* result = |
5537 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); | 5520 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); |
5538 result->set_transcendental_type(TranscendentalCache::COS); | 5521 result->set_transcendental_type(TranscendentalCache::COS); |
5539 Drop(1); | 5522 Drop(1); |
5540 ast_context()->ReturnInstruction(result, call->id()); | 5523 ast_context()->ReturnInstruction(result, call->id()); |
5541 } | 5524 } |
5542 | 5525 |
5543 | 5526 |
5544 void HGraphBuilder::GenerateMathLog(CallRuntime* call) { | 5527 void HGraphBuilder::GenerateMathLog(CallRuntime* call) { |
5545 ASSERT_EQ(1, call->arguments()->length()); | 5528 ASSERT_EQ(1, call->arguments()->length()); |
5546 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 5529 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
5547 HContext* context = new(zone()) HContext; | 5530 HValue* context = environment()->LookupContext(); |
5548 AddInstruction(context); | |
5549 HCallStub* result = | 5531 HCallStub* result = |
5550 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); | 5532 new(zone()) HCallStub(context, CodeStub::TranscendentalCache, 1); |
5551 result->set_transcendental_type(TranscendentalCache::LOG); | 5533 result->set_transcendental_type(TranscendentalCache::LOG); |
5552 Drop(1); | 5534 Drop(1); |
5553 ast_context()->ReturnInstruction(result, call->id()); | 5535 ast_context()->ReturnInstruction(result, call->id()); |
5554 } | 5536 } |
5555 | 5537 |
5556 | 5538 |
5557 void HGraphBuilder::GenerateMathSqrt(CallRuntime* call) { | 5539 void HGraphBuilder::GenerateMathSqrt(CallRuntime* call) { |
5558 return Bailout("inlined runtime function: MathSqrt"); | 5540 return Bailout("inlined runtime function: MathSqrt"); |
(...skipping 24 matching lines...) Expand all Loading... |
5583 #undef CHECK_ALIVE | 5565 #undef CHECK_ALIVE |
5584 | 5566 |
5585 | 5567 |
5586 HEnvironment::HEnvironment(HEnvironment* outer, | 5568 HEnvironment::HEnvironment(HEnvironment* outer, |
5587 Scope* scope, | 5569 Scope* scope, |
5588 Handle<JSFunction> closure) | 5570 Handle<JSFunction> closure) |
5589 : closure_(closure), | 5571 : closure_(closure), |
5590 values_(0), | 5572 values_(0), |
5591 assigned_variables_(4), | 5573 assigned_variables_(4), |
5592 parameter_count_(0), | 5574 parameter_count_(0), |
| 5575 specials_count_(1), |
5593 local_count_(0), | 5576 local_count_(0), |
5594 outer_(outer), | 5577 outer_(outer), |
5595 pop_count_(0), | 5578 pop_count_(0), |
5596 push_count_(0), | 5579 push_count_(0), |
5597 ast_id_(AstNode::kNoNumber) { | 5580 ast_id_(AstNode::kNoNumber) { |
5598 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); | 5581 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); |
5599 } | 5582 } |
5600 | 5583 |
5601 | 5584 |
5602 HEnvironment::HEnvironment(const HEnvironment* other) | 5585 HEnvironment::HEnvironment(const HEnvironment* other) |
5603 : values_(0), | 5586 : values_(0), |
5604 assigned_variables_(0), | 5587 assigned_variables_(0), |
5605 parameter_count_(0), | 5588 parameter_count_(0), |
| 5589 specials_count_(1), |
5606 local_count_(0), | 5590 local_count_(0), |
5607 outer_(NULL), | 5591 outer_(NULL), |
5608 pop_count_(0), | 5592 pop_count_(0), |
5609 push_count_(0), | 5593 push_count_(0), |
5610 ast_id_(other->ast_id()) { | 5594 ast_id_(other->ast_id()) { |
5611 Initialize(other); | 5595 Initialize(other); |
5612 } | 5596 } |
5613 | 5597 |
5614 | 5598 |
5615 void HEnvironment::Initialize(int parameter_count, | 5599 void HEnvironment::Initialize(int parameter_count, |
5616 int local_count, | 5600 int local_count, |
5617 int stack_height) { | 5601 int stack_height) { |
5618 parameter_count_ = parameter_count; | 5602 parameter_count_ = parameter_count; |
5619 local_count_ = local_count; | 5603 local_count_ = local_count; |
5620 | 5604 |
5621 // Avoid reallocating the temporaries' backing store on the first Push. | 5605 // Avoid reallocating the temporaries' backing store on the first Push. |
5622 int total = parameter_count + local_count + stack_height; | 5606 int total = parameter_count + specials_count_ + local_count + stack_height; |
5623 values_.Initialize(total + 4); | 5607 values_.Initialize(total + 4); |
5624 for (int i = 0; i < total; ++i) values_.Add(NULL); | 5608 for (int i = 0; i < total; ++i) values_.Add(NULL); |
5625 } | 5609 } |
5626 | 5610 |
5627 | 5611 |
5628 void HEnvironment::Initialize(const HEnvironment* other) { | 5612 void HEnvironment::Initialize(const HEnvironment* other) { |
5629 closure_ = other->closure(); | 5613 closure_ = other->closure(); |
5630 values_.AddAll(other->values_); | 5614 values_.AddAll(other->values_); |
5631 assigned_variables_.AddAll(other->assigned_variables_); | 5615 assigned_variables_.AddAll(other->assigned_variables_); |
5632 parameter_count_ = other->parameter_count_; | 5616 parameter_count_ = other->parameter_count_; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5671 void HEnvironment::Bind(int index, HValue* value) { | 5655 void HEnvironment::Bind(int index, HValue* value) { |
5672 ASSERT(value != NULL); | 5656 ASSERT(value != NULL); |
5673 if (!assigned_variables_.Contains(index)) { | 5657 if (!assigned_variables_.Contains(index)) { |
5674 assigned_variables_.Add(index); | 5658 assigned_variables_.Add(index); |
5675 } | 5659 } |
5676 values_[index] = value; | 5660 values_[index] = value; |
5677 } | 5661 } |
5678 | 5662 |
5679 | 5663 |
5680 bool HEnvironment::HasExpressionAt(int index) const { | 5664 bool HEnvironment::HasExpressionAt(int index) const { |
5681 return index >= parameter_count_ + local_count_; | 5665 return index >= parameter_count_ + specials_count_ + local_count_; |
5682 } | 5666 } |
5683 | 5667 |
5684 | 5668 |
5685 bool HEnvironment::ExpressionStackIsEmpty() const { | 5669 bool HEnvironment::ExpressionStackIsEmpty() const { |
5686 int first_expression = parameter_count() + local_count(); | 5670 int first_expression = parameter_count() + specials_count() + local_count(); |
5687 ASSERT(length() >= first_expression); | 5671 ASSERT(length() >= first_expression); |
5688 return length() == first_expression; | 5672 return length() == first_expression; |
5689 } | 5673 } |
5690 | 5674 |
5691 | 5675 |
5692 void HEnvironment::SetExpressionStackAt(int index_from_top, HValue* value) { | 5676 void HEnvironment::SetExpressionStackAt(int index_from_top, HValue* value) { |
5693 int count = index_from_top + 1; | 5677 int count = index_from_top + 1; |
5694 int index = values_.length() - count; | 5678 int index = values_.length() - count; |
5695 ASSERT(HasExpressionAt(index)); | 5679 ASSERT(HasExpressionAt(index)); |
5696 // The push count must include at least the element in question or else | 5680 // The push count must include at least the element in question or else |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5754 HValue* push = ExpressionStackAt(arity - i); | 5738 HValue* push = ExpressionStackAt(arity - i); |
5755 inner->SetValueAt(i, push); | 5739 inner->SetValueAt(i, push); |
5756 } | 5740 } |
5757 } else { | 5741 } else { |
5758 ASSERT(compilation_phase == LITHIUM); | 5742 ASSERT(compilation_phase == LITHIUM); |
5759 for (int i = 0; i <= arity; ++i) { // Include receiver. | 5743 for (int i = 0; i <= arity; ++i) { // Include receiver. |
5760 HValue* push = ExpressionStackAt(arity - i); | 5744 HValue* push = ExpressionStackAt(arity - i); |
5761 inner->SetValueAt(i, push); | 5745 inner->SetValueAt(i, push); |
5762 } | 5746 } |
5763 } | 5747 } |
5764 | 5748 inner->SetValueAt(arity + 1, outer->LookupContext()); |
5765 // Initialize the stack-allocated locals to undefined. | 5749 for (int i = arity + 2; i < inner->length(); ++i) { |
5766 int local_base = arity + 1; | 5750 inner->SetValueAt(i, undefined); |
5767 int local_count = function->scope()->num_stack_slots(); | |
5768 for (int i = 0; i < local_count; ++i) { | |
5769 inner->SetValueAt(local_base + i, undefined); | |
5770 } | 5751 } |
5771 | 5752 |
5772 inner->set_ast_id(AstNode::kFunctionEntryId); | 5753 inner->set_ast_id(AstNode::kFunctionEntryId); |
5773 return inner; | 5754 return inner; |
5774 } | 5755 } |
5775 | 5756 |
5776 | 5757 |
5777 void HEnvironment::PrintTo(StringStream* stream) { | 5758 void HEnvironment::PrintTo(StringStream* stream) { |
5778 for (int i = 0; i < length(); i++) { | 5759 for (int i = 0; i < length(); i++) { |
5779 if (i == 0) stream->Add("parameters\n"); | 5760 if (i == 0) stream->Add("parameters\n"); |
5780 if (i == parameter_count()) stream->Add("locals\n"); | 5761 if (i == parameter_count()) stream->Add("specials\n"); |
5781 if (i == parameter_count() + local_count()) stream->Add("expressions"); | 5762 if (i == parameter_count() + specials_count()) stream->Add("locals\n"); |
| 5763 if (i == parameter_count() + specials_count() + local_count()) { |
| 5764 stream->Add("expressions"); |
| 5765 } |
5782 HValue* val = values_.at(i); | 5766 HValue* val = values_.at(i); |
5783 stream->Add("%d: ", i); | 5767 stream->Add("%d: ", i); |
5784 if (val != NULL) { | 5768 if (val != NULL) { |
5785 val->PrintNameTo(stream); | 5769 val->PrintNameTo(stream); |
5786 } else { | 5770 } else { |
5787 stream->Add("NULL"); | 5771 stream->Add("NULL"); |
5788 } | 5772 } |
5789 stream->Add("\n"); | 5773 stream->Add("\n"); |
5790 } | 5774 } |
5791 } | 5775 } |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6097 } | 6081 } |
6098 } | 6082 } |
6099 | 6083 |
6100 #ifdef DEBUG | 6084 #ifdef DEBUG |
6101 if (graph_ != NULL) graph_->Verify(); | 6085 if (graph_ != NULL) graph_->Verify(); |
6102 if (allocator_ != NULL) allocator_->Verify(); | 6086 if (allocator_ != NULL) allocator_->Verify(); |
6103 #endif | 6087 #endif |
6104 } | 6088 } |
6105 | 6089 |
6106 } } // namespace v8::internal | 6090 } } // namespace v8::internal |
OLD | NEW |