| 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 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 LChunkBuilder builder(info, this, &allocator); | 599 LChunkBuilder builder(info, this, &allocator); |
| 600 LChunk* chunk = builder.Build(); | 600 LChunk* chunk = builder.Build(); |
| 601 if (chunk == NULL) return Handle<Code>::null(); | 601 if (chunk == NULL) return Handle<Code>::null(); |
| 602 | 602 |
| 603 if (!FLAG_alloc_lithium) return Handle<Code>::null(); | 603 if (!FLAG_alloc_lithium) return Handle<Code>::null(); |
| 604 | 604 |
| 605 allocator.Allocate(chunk); | 605 allocator.Allocate(chunk); |
| 606 | 606 |
| 607 if (!FLAG_use_lithium) return Handle<Code>::null(); | 607 if (!FLAG_use_lithium) return Handle<Code>::null(); |
| 608 | 608 |
| 609 MacroAssembler assembler(NULL, 0); | 609 MacroAssembler assembler(info->isolate(), NULL, 0); |
| 610 LCodeGen generator(chunk, &assembler, info); | 610 LCodeGen generator(chunk, &assembler, info); |
| 611 | 611 |
| 612 if (FLAG_eliminate_empty_blocks) { | 612 if (FLAG_eliminate_empty_blocks) { |
| 613 chunk->MarkEmptyBlocks(); | 613 chunk->MarkEmptyBlocks(); |
| 614 } | 614 } |
| 615 | 615 |
| 616 if (generator.GenerateCode()) { | 616 if (generator.GenerateCode()) { |
| 617 if (FLAG_trace_codegen) { | 617 if (FLAG_trace_codegen) { |
| 618 PrintF("Crankshaft Compiler - "); | 618 PrintF("Crankshaft Compiler - "); |
| 619 } | 619 } |
| (...skipping 1353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1973 | 1973 |
| 1974 FunctionState::~FunctionState() { | 1974 FunctionState::~FunctionState() { |
| 1975 delete test_context_; | 1975 delete test_context_; |
| 1976 owner_->set_function_state(outer_); | 1976 owner_->set_function_state(outer_); |
| 1977 } | 1977 } |
| 1978 | 1978 |
| 1979 | 1979 |
| 1980 // Implementation of utility classes to represent an expression's context in | 1980 // Implementation of utility classes to represent an expression's context in |
| 1981 // the AST. | 1981 // the AST. |
| 1982 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind) | 1982 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind) |
| 1983 : owner_(owner), kind_(kind), outer_(owner->ast_context()) { | 1983 : owner_(owner), |
| 1984 kind_(kind), |
| 1985 outer_(owner->ast_context()), |
| 1986 for_typeof_(false) { |
| 1984 owner->set_ast_context(this); // Push. | 1987 owner->set_ast_context(this); // Push. |
| 1985 #ifdef DEBUG | 1988 #ifdef DEBUG |
| 1986 original_length_ = owner->environment()->length(); | 1989 original_length_ = owner->environment()->length(); |
| 1987 #endif | 1990 #endif |
| 1988 } | 1991 } |
| 1989 | 1992 |
| 1990 | 1993 |
| 1991 AstContext::~AstContext() { | 1994 AstContext::~AstContext() { |
| 1992 owner_->set_ast_context(outer_); // Pop. | 1995 owner_->set_ast_context(outer_); // Pop. |
| 1993 } | 1996 } |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2117 Visit(expr); | 2120 Visit(expr); |
| 2118 } | 2121 } |
| 2119 | 2122 |
| 2120 | 2123 |
| 2121 void HGraphBuilder::VisitForValue(Expression* expr) { | 2124 void HGraphBuilder::VisitForValue(Expression* expr) { |
| 2122 ValueContext for_value(this); | 2125 ValueContext for_value(this); |
| 2123 Visit(expr); | 2126 Visit(expr); |
| 2124 } | 2127 } |
| 2125 | 2128 |
| 2126 | 2129 |
| 2130 void HGraphBuilder::VisitForTypeOf(Expression* expr) { |
| 2131 ValueContext for_value(this); |
| 2132 for_value.set_for_typeof(true); |
| 2133 Visit(expr); |
| 2134 } |
| 2135 |
| 2136 |
| 2137 |
| 2127 void HGraphBuilder::VisitForControl(Expression* expr, | 2138 void HGraphBuilder::VisitForControl(Expression* expr, |
| 2128 HBasicBlock* true_block, | 2139 HBasicBlock* true_block, |
| 2129 HBasicBlock* false_block) { | 2140 HBasicBlock* false_block) { |
| 2130 TestContext for_test(this, true_block, false_block); | 2141 TestContext for_test(this, true_block, false_block); |
| 2131 Visit(expr); | 2142 Visit(expr); |
| 2132 } | 2143 } |
| 2133 | 2144 |
| 2134 | 2145 |
| 2135 void HGraphBuilder::VisitArgument(Expression* expr) { | 2146 void HGraphBuilder::VisitArgument(Expression* expr) { |
| 2136 VISIT_FOR_VALUE(expr); | 2147 VISIT_FOR_VALUE(expr); |
| (...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2755 void HGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 2766 void HGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { |
| 2756 BAILOUT("TryFinallyStatement"); | 2767 BAILOUT("TryFinallyStatement"); |
| 2757 } | 2768 } |
| 2758 | 2769 |
| 2759 | 2770 |
| 2760 void HGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { | 2771 void HGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { |
| 2761 BAILOUT("DebuggerStatement"); | 2772 BAILOUT("DebuggerStatement"); |
| 2762 } | 2773 } |
| 2763 | 2774 |
| 2764 | 2775 |
| 2776 static Handle<SharedFunctionInfo> SearchSharedFunctionInfo( |
| 2777 Code* unoptimized_code, FunctionLiteral* expr) { |
| 2778 int start_position = expr->start_position(); |
| 2779 RelocIterator it(unoptimized_code); |
| 2780 for (;!it.done(); it.next()) { |
| 2781 RelocInfo* rinfo = it.rinfo(); |
| 2782 if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue; |
| 2783 Object* obj = rinfo->target_object(); |
| 2784 if (obj->IsSharedFunctionInfo()) { |
| 2785 SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj); |
| 2786 if (shared->start_position() == start_position) { |
| 2787 return Handle<SharedFunctionInfo>(shared); |
| 2788 } |
| 2789 } |
| 2790 } |
| 2791 |
| 2792 return Handle<SharedFunctionInfo>(); |
| 2793 } |
| 2794 |
| 2795 |
| 2765 void HGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | 2796 void HGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { |
| 2766 Handle<SharedFunctionInfo> shared_info = | 2797 Handle<SharedFunctionInfo> shared_info = |
| 2767 Compiler::BuildFunctionInfo(expr, info()->script()); | 2798 SearchSharedFunctionInfo(info()->shared_info()->code(), |
| 2799 expr); |
| 2800 if (shared_info.is_null()) { |
| 2801 shared_info = Compiler::BuildFunctionInfo(expr, info()->script()); |
| 2802 } |
| 2768 CHECK_BAILOUT; | 2803 CHECK_BAILOUT; |
| 2769 HFunctionLiteral* instr = | 2804 HFunctionLiteral* instr = |
| 2770 new HFunctionLiteral(shared_info, expr->pretenure()); | 2805 new HFunctionLiteral(shared_info, expr->pretenure()); |
| 2771 ast_context()->ReturnInstruction(instr, expr->id()); | 2806 ast_context()->ReturnInstruction(instr, expr->id()); |
| 2772 } | 2807 } |
| 2773 | 2808 |
| 2774 | 2809 |
| 2775 void HGraphBuilder::VisitSharedFunctionInfoLiteral( | 2810 void HGraphBuilder::VisitSharedFunctionInfoLiteral( |
| 2776 SharedFunctionInfoLiteral* expr) { | 2811 SharedFunctionInfoLiteral* expr) { |
| 2777 BAILOUT("SharedFunctionInfoLiteral"); | 2812 BAILOUT("SharedFunctionInfoLiteral"); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2797 CHECK_BAILOUT; | 2832 CHECK_BAILOUT; |
| 2798 | 2833 |
| 2799 if (!ast_context()->IsTest()) { | 2834 if (!ast_context()->IsTest()) { |
| 2800 HBasicBlock* join = CreateJoin(other, current_block(), expr->id()); | 2835 HBasicBlock* join = CreateJoin(other, current_block(), expr->id()); |
| 2801 set_current_block(join); | 2836 set_current_block(join); |
| 2802 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | 2837 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); |
| 2803 } | 2838 } |
| 2804 } | 2839 } |
| 2805 | 2840 |
| 2806 | 2841 |
| 2807 void HGraphBuilder::LookupGlobalPropertyCell(Variable* var, | 2842 HGraphBuilder::GlobalPropertyAccess HGraphBuilder::LookupGlobalProperty( |
| 2808 LookupResult* lookup, | 2843 Variable* var, LookupResult* lookup, bool is_store) { |
| 2809 bool is_store) { | 2844 if (var->is_this() || !info()->has_global_object()) { |
| 2810 if (var->is_this()) { | 2845 return kUseGeneric; |
| 2811 BAILOUT("global this reference"); | |
| 2812 } | |
| 2813 if (!info()->has_global_object()) { | |
| 2814 BAILOUT("no global object to optimize VariableProxy"); | |
| 2815 } | 2846 } |
| 2816 Handle<GlobalObject> global(info()->global_object()); | 2847 Handle<GlobalObject> global(info()->global_object()); |
| 2817 global->Lookup(*var->name(), lookup); | 2848 global->Lookup(*var->name(), lookup); |
| 2818 if (!lookup->IsProperty()) { | 2849 if (!lookup->IsProperty() || |
| 2819 BAILOUT("global variable cell not yet introduced"); | 2850 lookup->type() != NORMAL || |
| 2851 (is_store && lookup->IsReadOnly()) || |
| 2852 lookup->holder() != *global) { |
| 2853 return kUseGeneric; |
| 2820 } | 2854 } |
| 2821 if (lookup->type() != NORMAL) { | 2855 |
| 2822 BAILOUT("global variable has accessors"); | 2856 return kUseCell; |
| 2823 } | |
| 2824 if (is_store && lookup->IsReadOnly()) { | |
| 2825 BAILOUT("read-only global variable"); | |
| 2826 } | |
| 2827 if (lookup->holder() != *global) { | |
| 2828 BAILOUT("global property on prototype of global object"); | |
| 2829 } | |
| 2830 } | 2857 } |
| 2831 | 2858 |
| 2832 | 2859 |
| 2833 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) { | 2860 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) { |
| 2834 ASSERT(var->IsContextSlot()); | 2861 ASSERT(var->IsContextSlot()); |
| 2835 HInstruction* context = new HContext; | 2862 HInstruction* context = new HContext; |
| 2836 AddInstruction(context); | 2863 AddInstruction(context); |
| 2837 int length = info()->scope()->ContextChainLength(var->scope()); | 2864 int length = info()->scope()->ContextChainLength(var->scope()); |
| 2838 while (length-- > 0) { | 2865 while (length-- > 0) { |
| 2839 context = new HOuterContext(context); | 2866 context = new HOuterContext(context); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2855 } else if (variable->IsContextSlot()) { | 2882 } else if (variable->IsContextSlot()) { |
| 2856 if (variable->mode() == Variable::CONST) { | 2883 if (variable->mode() == Variable::CONST) { |
| 2857 BAILOUT("reference to const context slot"); | 2884 BAILOUT("reference to const context slot"); |
| 2858 } | 2885 } |
| 2859 HValue* context = BuildContextChainWalk(variable); | 2886 HValue* context = BuildContextChainWalk(variable); |
| 2860 int index = variable->AsSlot()->index(); | 2887 int index = variable->AsSlot()->index(); |
| 2861 HLoadContextSlot* instr = new HLoadContextSlot(context, index); | 2888 HLoadContextSlot* instr = new HLoadContextSlot(context, index); |
| 2862 ast_context()->ReturnInstruction(instr, expr->id()); | 2889 ast_context()->ReturnInstruction(instr, expr->id()); |
| 2863 } else if (variable->is_global()) { | 2890 } else if (variable->is_global()) { |
| 2864 LookupResult lookup; | 2891 LookupResult lookup; |
| 2865 LookupGlobalPropertyCell(variable, &lookup, false); | 2892 GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, false); |
| 2866 CHECK_BAILOUT; | |
| 2867 | 2893 |
| 2868 Handle<GlobalObject> global(info()->global_object()); | 2894 if (type == kUseCell && |
| 2869 // TODO(3039103): Handle global property load through an IC call when access | 2895 info()->global_object()->IsAccessCheckNeeded()) { |
| 2870 // checks are enabled. | 2896 type = kUseGeneric; |
| 2871 if (global->IsAccessCheckNeeded()) { | |
| 2872 BAILOUT("global object requires access check"); | |
| 2873 } | 2897 } |
| 2874 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 2898 |
| 2875 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); | 2899 if (type == kUseCell) { |
| 2876 HLoadGlobal* instr = new HLoadGlobal(cell, check_hole); | 2900 Handle<GlobalObject> global(info()->global_object()); |
| 2877 ast_context()->ReturnInstruction(instr, expr->id()); | 2901 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
| 2902 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); |
| 2903 HLoadGlobalCell* instr = new HLoadGlobalCell(cell, check_hole); |
| 2904 ast_context()->ReturnInstruction(instr, expr->id()); |
| 2905 } else { |
| 2906 HContext* context = new HContext; |
| 2907 AddInstruction(context); |
| 2908 HGlobalObject* global_object = new HGlobalObject(context); |
| 2909 AddInstruction(global_object); |
| 2910 HLoadGlobalGeneric* instr = |
| 2911 new HLoadGlobalGeneric(context, |
| 2912 global_object, |
| 2913 variable->name(), |
| 2914 ast_context()->is_for_typeof()); |
| 2915 instr->set_position(expr->position()); |
| 2916 ASSERT(instr->HasSideEffects()); |
| 2917 ast_context()->ReturnInstruction(instr, expr->id()); |
| 2918 } |
| 2878 } else { | 2919 } else { |
| 2879 BAILOUT("reference to a variable which requires dynamic lookup"); | 2920 BAILOUT("reference to a variable which requires dynamic lookup"); |
| 2880 } | 2921 } |
| 2881 } | 2922 } |
| 2882 | 2923 |
| 2883 | 2924 |
| 2884 void HGraphBuilder::VisitLiteral(Literal* expr) { | 2925 void HGraphBuilder::VisitLiteral(Literal* expr) { |
| 2885 HConstant* instr = new HConstant(expr->handle(), Representation::Tagged()); | 2926 HConstant* instr = new HConstant(expr->handle(), Representation::Tagged()); |
| 2886 ast_context()->ReturnInstruction(instr, expr->id()); | 2927 ast_context()->ReturnInstruction(instr, expr->id()); |
| 2887 } | 2928 } |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3238 | 3279 |
| 3239 | 3280 |
| 3240 // Because not every expression has a position and there is not common | 3281 // Because not every expression has a position and there is not common |
| 3241 // superclass of Assignment and CountOperation, we cannot just pass the | 3282 // superclass of Assignment and CountOperation, we cannot just pass the |
| 3242 // owning expression instead of position and ast_id separately. | 3283 // owning expression instead of position and ast_id separately. |
| 3243 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, | 3284 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, |
| 3244 HValue* value, | 3285 HValue* value, |
| 3245 int position, | 3286 int position, |
| 3246 int ast_id) { | 3287 int ast_id) { |
| 3247 LookupResult lookup; | 3288 LookupResult lookup; |
| 3248 LookupGlobalPropertyCell(var, &lookup, true); | 3289 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true); |
| 3249 CHECK_BAILOUT; | 3290 if (type == kUseCell) { |
| 3250 | 3291 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); |
| 3251 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); | 3292 Handle<GlobalObject> global(info()->global_object()); |
| 3252 Handle<GlobalObject> global(info()->global_object()); | 3293 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); |
| 3253 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); | 3294 HInstruction* instr = new HStoreGlobalCell(value, cell, check_hole); |
| 3254 HInstruction* instr = new HStoreGlobal(value, cell, check_hole); | 3295 instr->set_position(position); |
| 3255 instr->set_position(position); | 3296 AddInstruction(instr); |
| 3256 AddInstruction(instr); | 3297 if (instr->HasSideEffects()) AddSimulate(ast_id); |
| 3257 if (instr->HasSideEffects()) AddSimulate(ast_id); | 3298 } else { |
| 3299 HContext* context = new HContext; |
| 3300 AddInstruction(context); |
| 3301 HGlobalObject* global_object = new HGlobalObject(context); |
| 3302 AddInstruction(global_object); |
| 3303 HStoreGlobalGeneric* instr = |
| 3304 new HStoreGlobalGeneric(context, |
| 3305 global_object, |
| 3306 var->name(), |
| 3307 value); |
| 3308 instr->set_position(position); |
| 3309 AddInstruction(instr); |
| 3310 ASSERT(instr->HasSideEffects()); |
| 3311 if (instr->HasSideEffects()) AddSimulate(ast_id); |
| 3312 } |
| 3258 } | 3313 } |
| 3259 | 3314 |
| 3260 | 3315 |
| 3261 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { | 3316 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
| 3262 Expression* target = expr->target(); | 3317 Expression* target = expr->target(); |
| 3263 VariableProxy* proxy = target->AsVariableProxy(); | 3318 VariableProxy* proxy = target->AsVariableProxy(); |
| 3264 Variable* var = proxy->AsVariable(); | 3319 Variable* var = proxy->AsVariable(); |
| 3265 Property* prop = target->AsProperty(); | 3320 Property* prop = target->AsProperty(); |
| 3266 ASSERT(var == NULL || prop == NULL); | 3321 ASSERT(var == NULL || prop == NULL); |
| 3267 | 3322 |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3844 set_current_block(join); | 3899 set_current_block(join); |
| 3845 if (join->HasPredecessor()) { | 3900 if (join->HasPredecessor()) { |
| 3846 join->SetJoinId(expr->id()); | 3901 join->SetJoinId(expr->id()); |
| 3847 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | 3902 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); |
| 3848 } | 3903 } |
| 3849 } | 3904 } |
| 3850 | 3905 |
| 3851 | 3906 |
| 3852 void HGraphBuilder::TraceInline(Handle<JSFunction> target, const char* reason) { | 3907 void HGraphBuilder::TraceInline(Handle<JSFunction> target, const char* reason) { |
| 3853 if (FLAG_trace_inlining) { | 3908 if (FLAG_trace_inlining) { |
| 3854 SmartPointer<char> callee = target->shared()->DebugName()->ToCString(); | |
| 3855 SmartPointer<char> caller = | |
| 3856 info()->function()->debug_name()->ToCString(); | |
| 3857 if (reason == NULL) { | 3909 if (reason == NULL) { |
| 3910 // We are currently in the context of inlined function thus we have |
| 3911 // to go to an outer FunctionState to get caller. |
| 3912 SmartPointer<char> callee = target->shared()->DebugName()->ToCString(); |
| 3913 SmartPointer<char> caller = |
| 3914 function_state()->outer()->compilation_info()->function()-> |
| 3915 debug_name()->ToCString(); |
| 3858 PrintF("Inlined %s called from %s.\n", *callee, *caller); | 3916 PrintF("Inlined %s called from %s.\n", *callee, *caller); |
| 3859 } else { | 3917 } else { |
| 3918 SmartPointer<char> callee = target->shared()->DebugName()->ToCString(); |
| 3919 SmartPointer<char> caller = |
| 3920 info()->function()->debug_name()->ToCString(); |
| 3860 PrintF("Did not inline %s called from %s (%s).\n", | 3921 PrintF("Did not inline %s called from %s (%s).\n", |
| 3861 *callee, *caller, reason); | 3922 *callee, *caller, reason); |
| 3862 } | 3923 } |
| 3863 } | 3924 } |
| 3864 } | 3925 } |
| 3865 | 3926 |
| 3866 | 3927 |
| 3867 bool HGraphBuilder::TryInline(Call* expr) { | 3928 bool HGraphBuilder::TryInline(Call* expr) { |
| 3868 if (!FLAG_use_inlining) return false; | 3929 if (!FLAG_use_inlining) return false; |
| 3869 | 3930 |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4303 if (!global_call) { | 4364 if (!global_call) { |
| 4304 ++argument_count; | 4365 ++argument_count; |
| 4305 VISIT_FOR_VALUE(expr->expression()); | 4366 VISIT_FOR_VALUE(expr->expression()); |
| 4306 } | 4367 } |
| 4307 | 4368 |
| 4308 if (global_call) { | 4369 if (global_call) { |
| 4309 bool known_global_function = false; | 4370 bool known_global_function = false; |
| 4310 // If there is a global property cell for the name at compile time and | 4371 // If there is a global property cell for the name at compile time and |
| 4311 // access check is not enabled we assume that the function will not change | 4372 // access check is not enabled we assume that the function will not change |
| 4312 // and generate optimized code for calling the function. | 4373 // and generate optimized code for calling the function. |
| 4313 if (info()->has_global_object() && | 4374 LookupResult lookup; |
| 4375 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); |
| 4376 if (type == kUseCell && |
| 4314 !info()->global_object()->IsAccessCheckNeeded()) { | 4377 !info()->global_object()->IsAccessCheckNeeded()) { |
| 4315 Handle<GlobalObject> global(info()->global_object()); | 4378 Handle<GlobalObject> global(info()->global_object()); |
| 4316 known_global_function = expr->ComputeGlobalTarget(global, var->name()); | 4379 known_global_function = expr->ComputeGlobalTarget(global, &lookup); |
| 4317 } | 4380 } |
| 4318 if (known_global_function) { | 4381 if (known_global_function) { |
| 4319 // Push the global object instead of the global receiver because | 4382 // Push the global object instead of the global receiver because |
| 4320 // code generated by the full code generator expects it. | 4383 // code generated by the full code generator expects it. |
| 4321 HContext* context = new HContext; | 4384 HContext* context = new HContext; |
| 4322 HGlobalObject* global_object = new HGlobalObject(context); | 4385 HGlobalObject* global_object = new HGlobalObject(context); |
| 4323 AddInstruction(context); | 4386 AddInstruction(context); |
| 4324 PushAndAdd(global_object); | 4387 PushAndAdd(global_object); |
| 4325 VisitExpressions(expr->arguments()); | 4388 VisitExpressions(expr->arguments()); |
| 4326 CHECK_BAILOUT; | 4389 CHECK_BAILOUT; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4503 HBasicBlock* join = | 4566 HBasicBlock* join = |
| 4504 CreateJoin(materialize_false, materialize_true, expr->id()); | 4567 CreateJoin(materialize_false, materialize_true, expr->id()); |
| 4505 set_current_block(join); | 4568 set_current_block(join); |
| 4506 ast_context()->ReturnValue(Pop()); | 4569 ast_context()->ReturnValue(Pop()); |
| 4507 } else { | 4570 } else { |
| 4508 ASSERT(ast_context()->IsEffect()); | 4571 ASSERT(ast_context()->IsEffect()); |
| 4509 VisitForEffect(expr->expression()); | 4572 VisitForEffect(expr->expression()); |
| 4510 } | 4573 } |
| 4511 | 4574 |
| 4512 } else if (op == Token::TYPEOF) { | 4575 } else if (op == Token::TYPEOF) { |
| 4513 VISIT_FOR_VALUE(expr->expression()); | 4576 VisitForTypeOf(expr->expression()); |
| 4577 if (HasStackOverflow()) return; |
| 4514 HValue* value = Pop(); | 4578 HValue* value = Pop(); |
| 4515 ast_context()->ReturnInstruction(new HTypeof(value), expr->id()); | 4579 ast_context()->ReturnInstruction(new HTypeof(value), expr->id()); |
| 4516 | 4580 |
| 4517 } else { | 4581 } else { |
| 4518 VISIT_FOR_VALUE(expr->expression()); | 4582 VISIT_FOR_VALUE(expr->expression()); |
| 4519 HValue* value = Pop(); | 4583 HValue* value = Pop(); |
| 4520 HInstruction* instr = NULL; | 4584 HInstruction* instr = NULL; |
| 4521 switch (op) { | 4585 switch (op) { |
| 4522 case Token::BIT_NOT: | 4586 case Token::BIT_NOT: |
| 4523 instr = new HBitNot(value); | 4587 instr = new HBitNot(value); |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4920 ast_context()->ReturnInstruction(instr, expr->id()); | 4984 ast_context()->ReturnInstruction(instr, expr->id()); |
| 4921 return; | 4985 return; |
| 4922 } | 4986 } |
| 4923 | 4987 |
| 4924 // Check for the pattern: typeof <expression> == <string literal>. | 4988 // Check for the pattern: typeof <expression> == <string literal>. |
| 4925 UnaryOperation* left_unary = expr->left()->AsUnaryOperation(); | 4989 UnaryOperation* left_unary = expr->left()->AsUnaryOperation(); |
| 4926 Literal* right_literal = expr->right()->AsLiteral(); | 4990 Literal* right_literal = expr->right()->AsLiteral(); |
| 4927 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) && | 4991 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) && |
| 4928 left_unary != NULL && left_unary->op() == Token::TYPEOF && | 4992 left_unary != NULL && left_unary->op() == Token::TYPEOF && |
| 4929 right_literal != NULL && right_literal->handle()->IsString()) { | 4993 right_literal != NULL && right_literal->handle()->IsString()) { |
| 4930 VISIT_FOR_VALUE(left_unary->expression()); | 4994 VisitForTypeOf(left_unary->expression()); |
| 4995 if (HasStackOverflow()) return; |
| 4931 HValue* left = Pop(); | 4996 HValue* left = Pop(); |
| 4932 HInstruction* instr = new HTypeofIs(left, | 4997 HInstruction* instr = new HTypeofIs(left, |
| 4933 Handle<String>::cast(right_literal->handle())); | 4998 Handle<String>::cast(right_literal->handle())); |
| 4934 instr->set_position(expr->position()); | 4999 instr->set_position(expr->position()); |
| 4935 ast_context()->ReturnInstruction(instr, expr->id()); | 5000 ast_context()->ReturnInstruction(instr, expr->id()); |
| 4936 return; | 5001 return; |
| 4937 } | 5002 } |
| 4938 | 5003 |
| 4939 VISIT_FOR_VALUE(expr->left()); | 5004 VISIT_FOR_VALUE(expr->left()); |
| 4940 VISIT_FOR_VALUE(expr->right()); | 5005 VISIT_FOR_VALUE(expr->right()); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5117 | 5182 |
| 5118 void HGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( | 5183 void HGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( |
| 5119 CallRuntime* call) { | 5184 CallRuntime* call) { |
| 5120 BAILOUT("inlined runtime function: IsStringWrapperSafeForDefaultValueOf"); | 5185 BAILOUT("inlined runtime function: IsStringWrapperSafeForDefaultValueOf"); |
| 5121 } | 5186 } |
| 5122 | 5187 |
| 5123 | 5188 |
| 5124 // Support for construct call checks. | 5189 // Support for construct call checks. |
| 5125 void HGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { | 5190 void HGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { |
| 5126 ASSERT(call->arguments()->length() == 0); | 5191 ASSERT(call->arguments()->length() == 0); |
| 5127 ast_context()->ReturnInstruction(new HIsConstructCall, call->id()); | 5192 if (function_state()->outer() != NULL) { |
| 5193 // We are generating graph for inlined function. Currently |
| 5194 // constructor inlining is not supported and we can just return |
| 5195 // false from %_IsConstructCall(). |
| 5196 ast_context()->ReturnValue(graph()->GetConstantFalse()); |
| 5197 } else { |
| 5198 ast_context()->ReturnInstruction(new HIsConstructCall, call->id()); |
| 5199 } |
| 5128 } | 5200 } |
| 5129 | 5201 |
| 5130 | 5202 |
| 5131 // Support for arguments.length and arguments[?]. | 5203 // Support for arguments.length and arguments[?]. |
| 5132 void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { | 5204 void HGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { |
| 5133 ASSERT(call->arguments()->length() == 0); | 5205 ASSERT(call->arguments()->length() == 0); |
| 5134 HInstruction* elements = AddInstruction(new HArgumentsElements); | 5206 HInstruction* elements = AddInstruction(new HArgumentsElements); |
| 5135 HArgumentsLength* result = new HArgumentsLength(elements); | 5207 HArgumentsLength* result = new HArgumentsLength(elements); |
| 5136 ast_context()->ReturnInstruction(result, call->id()); | 5208 ast_context()->ReturnInstruction(result, call->id()); |
| 5137 } | 5209 } |
| (...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5922 } | 5994 } |
| 5923 } | 5995 } |
| 5924 | 5996 |
| 5925 #ifdef DEBUG | 5997 #ifdef DEBUG |
| 5926 if (graph_ != NULL) graph_->Verify(); | 5998 if (graph_ != NULL) graph_->Verify(); |
| 5927 if (allocator_ != NULL) allocator_->Verify(); | 5999 if (allocator_ != NULL) allocator_->Verify(); |
| 5928 #endif | 6000 #endif |
| 5929 } | 6001 } |
| 5930 | 6002 |
| 5931 } } // namespace v8::internal | 6003 } } // namespace v8::internal |
| OLD | NEW |