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