Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(415)

Side by Side Diff: src/hydrogen.cc

Issue 6665026: Increase coverage of global loads in optimized code... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 1943 matching lines...) Expand 10 before | Expand all | Expand 10 after
1954 1954
1955 FunctionState::~FunctionState() { 1955 FunctionState::~FunctionState() {
1956 delete test_context_; 1956 delete test_context_;
1957 owner_->set_function_state(outer_); 1957 owner_->set_function_state(outer_);
1958 } 1958 }
1959 1959
1960 1960
1961 // Implementation of utility classes to represent an expression's context in 1961 // Implementation of utility classes to represent an expression's context in
1962 // the AST. 1962 // the AST.
1963 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind) 1963 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind)
1964 : owner_(owner), kind_(kind), outer_(owner->ast_context()) { 1964 : owner_(owner),
1965 kind_(kind),
1966 outer_(owner->ast_context()),
1967 for_typeof_(false) {
1965 owner->set_ast_context(this); // Push. 1968 owner->set_ast_context(this); // Push.
1966 #ifdef DEBUG 1969 #ifdef DEBUG
1967 original_length_ = owner->environment()->length(); 1970 original_length_ = owner->environment()->length();
1968 #endif 1971 #endif
1969 } 1972 }
1970 1973
1971 1974
1972 AstContext::~AstContext() { 1975 AstContext::~AstContext() {
1973 owner_->set_ast_context(outer_); // Pop. 1976 owner_->set_ast_context(outer_); // Pop.
1974 } 1977 }
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2098 Visit(expr); 2101 Visit(expr);
2099 } 2102 }
2100 2103
2101 2104
2102 void HGraphBuilder::VisitForValue(Expression* expr) { 2105 void HGraphBuilder::VisitForValue(Expression* expr) {
2103 ValueContext for_value(this); 2106 ValueContext for_value(this);
2104 Visit(expr); 2107 Visit(expr);
2105 } 2108 }
2106 2109
2107 2110
2111 void HGraphBuilder::VisitForTypeOf(Expression* expr) {
2112 ValueContext for_value(this);
2113 for_value.set_for_typeof(true);
2114 Visit(expr);
2115 }
2116
2117
2118
2108 void HGraphBuilder::VisitForControl(Expression* expr, 2119 void HGraphBuilder::VisitForControl(Expression* expr,
2109 HBasicBlock* true_block, 2120 HBasicBlock* true_block,
2110 HBasicBlock* false_block) { 2121 HBasicBlock* false_block) {
2111 TestContext for_test(this, true_block, false_block); 2122 TestContext for_test(this, true_block, false_block);
2112 Visit(expr); 2123 Visit(expr);
2113 } 2124 }
2114 2125
2115 2126
2116 void HGraphBuilder::VisitArgument(Expression* expr) { 2127 void HGraphBuilder::VisitArgument(Expression* expr) {
2117 VISIT_FOR_VALUE(expr); 2128 VISIT_FOR_VALUE(expr);
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after
2790 CHECK_BAILOUT; 2801 CHECK_BAILOUT;
2791 2802
2792 if (!ast_context()->IsTest()) { 2803 if (!ast_context()->IsTest()) {
2793 HBasicBlock* join = CreateJoin(other, current_block(), expr->id()); 2804 HBasicBlock* join = CreateJoin(other, current_block(), expr->id());
2794 set_current_block(join); 2805 set_current_block(join);
2795 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 2806 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
2796 } 2807 }
2797 } 2808 }
2798 2809
2799 2810
2800 void HGraphBuilder::LookupGlobalPropertyCell(Variable* var, 2811 HGraphBuilder::GlobalPropertyAccess HGraphBuilder::LookupGlobalProperty(
2801 LookupResult* lookup, 2812 Variable* var, LookupResult* lookup, bool is_store) {
2802 bool is_store) {
2803 if (var->is_this()) { 2813 if (var->is_this()) {
2804 BAILOUT("global this reference"); 2814 return kUseGeneric;
fschneider 2011/03/16 10:28:18 I'd move this into the same line as the if-stateme
Søren Thygesen Gjesse 2011/03/17 07:52:27 Done.
2805 } 2815 }
2806 if (!info()->has_global_object()) { 2816 if (!info()->has_global_object()) {
2807 BAILOUT("no global object to optimize VariableProxy"); 2817 return kUseGeneric;
2808 } 2818 }
2809 Handle<GlobalObject> global(info()->global_object()); 2819 Handle<GlobalObject> global(info()->global_object());
2810 global->Lookup(*var->name(), lookup); 2820 global->Lookup(*var->name(), lookup);
2811 if (!lookup->IsProperty()) { 2821 if (!lookup->IsProperty()) {
2812 BAILOUT("global variable cell not yet introduced"); 2822 return kUseGeneric;
2813 } 2823 }
2814 if (lookup->type() != NORMAL) { 2824 if (lookup->type() != NORMAL) {
2815 BAILOUT("global variable has accessors"); 2825 return kUseGeneric;
2816 } 2826 }
2817 if (is_store && lookup->IsReadOnly()) { 2827 if (is_store && lookup->IsReadOnly()) {
2818 BAILOUT("read-only global variable"); 2828 return kUseGeneric;
2819 } 2829 }
2820 if (lookup->holder() != *global) { 2830 if (lookup->holder() != *global) {
2821 BAILOUT("global property on prototype of global object"); 2831 return kUseGeneric;
2822 } 2832 }
2833
2834 return kUseCell;
2823 } 2835 }
2824 2836
2825 2837
2826 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) { 2838 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) {
2827 ASSERT(var->IsContextSlot()); 2839 ASSERT(var->IsContextSlot());
2828 HInstruction* context = new HContext; 2840 HInstruction* context = new HContext;
2829 AddInstruction(context); 2841 AddInstruction(context);
2830 int length = info()->scope()->ContextChainLength(var->scope()); 2842 int length = info()->scope()->ContextChainLength(var->scope());
2831 while (length-- > 0) { 2843 while (length-- > 0) {
2832 context = new HOuterContext(context); 2844 context = new HOuterContext(context);
(...skipping 15 matching lines...) Expand all
2848 } else if (variable->IsContextSlot()) { 2860 } else if (variable->IsContextSlot()) {
2849 if (variable->mode() == Variable::CONST) { 2861 if (variable->mode() == Variable::CONST) {
2850 BAILOUT("reference to const context slot"); 2862 BAILOUT("reference to const context slot");
2851 } 2863 }
2852 HValue* context = BuildContextChainWalk(variable); 2864 HValue* context = BuildContextChainWalk(variable);
2853 int index = variable->AsSlot()->index(); 2865 int index = variable->AsSlot()->index();
2854 HLoadContextSlot* instr = new HLoadContextSlot(context, index); 2866 HLoadContextSlot* instr = new HLoadContextSlot(context, index);
2855 ast_context()->ReturnInstruction(instr, expr->id()); 2867 ast_context()->ReturnInstruction(instr, expr->id());
2856 } else if (variable->is_global()) { 2868 } else if (variable->is_global()) {
2857 LookupResult lookup; 2869 LookupResult lookup;
2858 LookupGlobalPropertyCell(variable, &lookup, false); 2870 GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, false);
2859 CHECK_BAILOUT;
2860 2871
2861 Handle<GlobalObject> global(info()->global_object()); 2872 if (type == kUseCell &&
2862 // TODO(3039103): Handle global property load through an IC call when access 2873 info()->global_object()->IsAccessCheckNeeded()) {
2863 // checks are enabled. 2874 type = kUseGeneric;
2864 if (global->IsAccessCheckNeeded()) {
2865 BAILOUT("global object requires access check");
2866 } 2875 }
2867 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 2876
2868 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); 2877 if (type == kUseCell) {
2869 HLoadGlobal* instr = new HLoadGlobal(cell, check_hole); 2878 Handle<GlobalObject> global(info()->global_object());
2870 ast_context()->ReturnInstruction(instr, expr->id()); 2879 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
2880 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
2881 HLoadGlobalCell* instr = new HLoadGlobalCell(cell, check_hole);
2882 ast_context()->ReturnInstruction(instr, expr->id());
2883 } else {
2884 HContext* context = new HContext;
2885 AddInstruction(context);
2886 HLoadGlobalGeneric* instr =
2887 new HLoadGlobalGeneric(
2888 context, variable->name(), ast_context()->is_for_typeof());
2889 ast_context()->ReturnInstruction(instr, expr->id());
2890 }
2871 } else { 2891 } else {
2872 BAILOUT("reference to a variable which requires dynamic lookup"); 2892 BAILOUT("reference to a variable which requires dynamic lookup");
2873 } 2893 }
2874 } 2894 }
2875 2895
2876 2896
2877 void HGraphBuilder::VisitLiteral(Literal* expr) { 2897 void HGraphBuilder::VisitLiteral(Literal* expr) {
2878 HConstant* instr = new HConstant(expr->handle(), Representation::Tagged()); 2898 HConstant* instr = new HConstant(expr->handle(), Representation::Tagged());
2879 ast_context()->ReturnInstruction(instr, expr->id()); 2899 ast_context()->ReturnInstruction(instr, expr->id());
2880 } 2900 }
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
3217 3237
3218 3238
3219 // Because not every expression has a position and there is not common 3239 // Because not every expression has a position and there is not common
3220 // superclass of Assignment and CountOperation, we cannot just pass the 3240 // superclass of Assignment and CountOperation, we cannot just pass the
3221 // owning expression instead of position and ast_id separately. 3241 // owning expression instead of position and ast_id separately.
3222 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, 3242 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var,
3223 HValue* value, 3243 HValue* value,
3224 int position, 3244 int position,
3225 int ast_id) { 3245 int ast_id) {
3226 LookupResult lookup; 3246 LookupResult lookup;
3227 LookupGlobalPropertyCell(var, &lookup, true); 3247 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
3228 CHECK_BAILOUT; 3248 if (type == kUseCell) {
3229 3249 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
3230 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); 3250 Handle<GlobalObject> global(info()->global_object());
3231 Handle<GlobalObject> global(info()->global_object()); 3251 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
3232 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 3252 HInstruction* instr = new HStoreGlobal(value, cell, check_hole);
3233 HInstruction* instr = new HStoreGlobal(value, cell, check_hole); 3253 instr->set_position(position);
3234 instr->set_position(position); 3254 AddInstruction(instr);
3235 AddInstruction(instr); 3255 if (instr->HasSideEffects()) AddSimulate(ast_id);
3236 if (instr->HasSideEffects()) AddSimulate(ast_id); 3256 } else {
3257 BAILOUT("global store only supported for cells");
3258 }
3237 } 3259 }
3238 3260
3239 3261
3240 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 3262 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
3241 Expression* target = expr->target(); 3263 Expression* target = expr->target();
3242 VariableProxy* proxy = target->AsVariableProxy(); 3264 VariableProxy* proxy = target->AsVariableProxy();
3243 Variable* var = proxy->AsVariable(); 3265 Variable* var = proxy->AsVariable();
3244 Property* prop = target->AsProperty(); 3266 Property* prop = target->AsProperty();
3245 ASSERT(var == NULL || prop == NULL); 3267 ASSERT(var == NULL || prop == NULL);
3246 3268
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after
4321 if (!global_call) { 4343 if (!global_call) {
4322 ++argument_count; 4344 ++argument_count;
4323 VISIT_FOR_VALUE(expr->expression()); 4345 VISIT_FOR_VALUE(expr->expression());
4324 } 4346 }
4325 4347
4326 if (global_call) { 4348 if (global_call) {
4327 bool known_global_function = false; 4349 bool known_global_function = false;
4328 // If there is a global property cell for the name at compile time and 4350 // If there is a global property cell for the name at compile time and
4329 // access check is not enabled we assume that the function will not change 4351 // access check is not enabled we assume that the function will not change
4330 // and generate optimized code for calling the function. 4352 // and generate optimized code for calling the function.
4331 if (info()->has_global_object() && 4353 LookupResult lookup;
4354 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false);
4355 if (type == kUseCell &&
4332 !info()->global_object()->IsAccessCheckNeeded()) { 4356 !info()->global_object()->IsAccessCheckNeeded()) {
4333 Handle<GlobalObject> global(info()->global_object()); 4357 Handle<GlobalObject> global(info()->global_object());
4334 known_global_function = expr->ComputeGlobalTarget(global, var->name()); 4358 known_global_function = expr->ComputeGlobalTarget(global, lookup);
4335 } 4359 }
4336 if (known_global_function) { 4360 if (known_global_function) {
4337 // Push the global object instead of the global receiver because 4361 // Push the global object instead of the global receiver because
4338 // code generated by the full code generator expects it. 4362 // code generated by the full code generator expects it.
4339 HContext* context = new HContext; 4363 HContext* context = new HContext;
4340 HGlobalObject* global_object = new HGlobalObject(context); 4364 HGlobalObject* global_object = new HGlobalObject(context);
4341 AddInstruction(context); 4365 AddInstruction(context);
4342 PushAndAdd(global_object); 4366 PushAndAdd(global_object);
4343 VisitExpressions(expr->arguments()); 4367 VisitExpressions(expr->arguments());
4344 CHECK_BAILOUT; 4368 CHECK_BAILOUT;
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
4543 break; 4567 break;
4544 case Token::SUB: 4568 case Token::SUB:
4545 instr = new HMul(graph_->GetConstantMinus1(), value); 4569 instr = new HMul(graph_->GetConstantMinus1(), value);
4546 break; 4570 break;
4547 default: 4571 default:
4548 UNREACHABLE(); 4572 UNREACHABLE();
4549 break; 4573 break;
4550 } 4574 }
4551 ast_context()->ReturnInstruction(instr, expr->id()); 4575 ast_context()->ReturnInstruction(instr, expr->id());
4552 } else if (op == Token::TYPEOF) { 4576 } else if (op == Token::TYPEOF) {
4553 VISIT_FOR_VALUE(expr->expression()); 4577 VisitForTypeOf(expr);
4578 if (HasStackOverflow()) return;
4554 HValue* value = Pop(); 4579 HValue* value = Pop();
4555 ast_context()->ReturnInstruction(new HTypeof(value), expr->id()); 4580 ast_context()->ReturnInstruction(new HTypeof(value), expr->id());
4556 } else { 4581 } else {
4557 BAILOUT("Value: unsupported unary operation"); 4582 BAILOUT("Value: unsupported unary operation");
4558 } 4583 }
4559 } 4584 }
4560 4585
4561 4586
4562 void HGraphBuilder::VisitIncrementOperation(IncrementOperation* expr) { 4587 void HGraphBuilder::VisitIncrementOperation(IncrementOperation* expr) {
4563 // IncrementOperation is never visited by the visitor. It only 4588 // IncrementOperation is never visited by the visitor. It only
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
4928 ast_context()->ReturnInstruction(instr, expr->id()); 4953 ast_context()->ReturnInstruction(instr, expr->id());
4929 return; 4954 return;
4930 } 4955 }
4931 4956
4932 // Check for the pattern: typeof <expression> == <string literal>. 4957 // Check for the pattern: typeof <expression> == <string literal>.
4933 UnaryOperation* left_unary = expr->left()->AsUnaryOperation(); 4958 UnaryOperation* left_unary = expr->left()->AsUnaryOperation();
4934 Literal* right_literal = expr->right()->AsLiteral(); 4959 Literal* right_literal = expr->right()->AsLiteral();
4935 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) && 4960 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) &&
4936 left_unary != NULL && left_unary->op() == Token::TYPEOF && 4961 left_unary != NULL && left_unary->op() == Token::TYPEOF &&
4937 right_literal != NULL && right_literal->handle()->IsString()) { 4962 right_literal != NULL && right_literal->handle()->IsString()) {
4938 VISIT_FOR_VALUE(left_unary->expression()); 4963 VisitForTypeOf(expr);
4964 if (HasStackOverflow()) return;
4939 HValue* left = Pop(); 4965 HValue* left = Pop();
4940 HInstruction* instr = new HTypeofIs(left, 4966 HInstruction* instr = new HTypeofIs(left,
4941 Handle<String>::cast(right_literal->handle())); 4967 Handle<String>::cast(right_literal->handle()));
4942 instr->set_position(expr->position()); 4968 instr->set_position(expr->position());
4943 ast_context()->ReturnInstruction(instr, expr->id()); 4969 ast_context()->ReturnInstruction(instr, expr->id());
4944 return; 4970 return;
4945 } 4971 }
4946 4972
4947 VISIT_FOR_VALUE(expr->left()); 4973 VISIT_FOR_VALUE(expr->left());
4948 VISIT_FOR_VALUE(expr->right()); 4974 VISIT_FOR_VALUE(expr->right());
(...skipping 976 matching lines...) Expand 10 before | Expand all | Expand 10 after
5925 } 5951 }
5926 } 5952 }
5927 5953
5928 #ifdef DEBUG 5954 #ifdef DEBUG
5929 if (graph_ != NULL) graph_->Verify(); 5955 if (graph_ != NULL) graph_->Verify();
5930 if (allocator_ != NULL) allocator_->Verify(); 5956 if (allocator_ != NULL) allocator_->Verify();
5931 #endif 5957 #endif
5932 } 5958 }
5933 5959
5934 } } // namespace v8::internal 5960 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698