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

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
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) { 2813 if (var->is_this() || !info()->has_global_object()) {
2803 if (var->is_this()) { 2814 return kUseGeneric;
2804 BAILOUT("global this reference");
2805 }
2806 if (!info()->has_global_object()) {
2807 BAILOUT("no global object to optimize VariableProxy");
2808 } 2815 }
2809 Handle<GlobalObject> global(info()->global_object()); 2816 Handle<GlobalObject> global(info()->global_object());
2810 global->Lookup(*var->name(), lookup); 2817 global->Lookup(*var->name(), lookup);
2811 if (!lookup->IsProperty()) { 2818 if (!lookup->IsProperty() ||
2812 BAILOUT("global variable cell not yet introduced"); 2819 lookup->type() != NORMAL ||
2820 (is_store && lookup->IsReadOnly()) ||
2821 lookup->holder() != *global) {
2822 return kUseGeneric;
2813 } 2823 }
2814 if (lookup->type() != NORMAL) { 2824
2815 BAILOUT("global variable has accessors"); 2825 return kUseCell;
2816 }
2817 if (is_store && lookup->IsReadOnly()) {
2818 BAILOUT("read-only global variable");
2819 }
2820 if (lookup->holder() != *global) {
2821 BAILOUT("global property on prototype of global object");
2822 }
2823 } 2826 }
2824 2827
2825 2828
2826 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) { 2829 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) {
2827 ASSERT(var->IsContextSlot()); 2830 ASSERT(var->IsContextSlot());
2828 HInstruction* context = new HContext; 2831 HInstruction* context = new HContext;
2829 AddInstruction(context); 2832 AddInstruction(context);
2830 int length = info()->scope()->ContextChainLength(var->scope()); 2833 int length = info()->scope()->ContextChainLength(var->scope());
2831 while (length-- > 0) { 2834 while (length-- > 0) {
2832 context = new HOuterContext(context); 2835 context = new HOuterContext(context);
(...skipping 15 matching lines...) Expand all
2848 } else if (variable->IsContextSlot()) { 2851 } else if (variable->IsContextSlot()) {
2849 if (variable->mode() == Variable::CONST) { 2852 if (variable->mode() == Variable::CONST) {
2850 BAILOUT("reference to const context slot"); 2853 BAILOUT("reference to const context slot");
2851 } 2854 }
2852 HValue* context = BuildContextChainWalk(variable); 2855 HValue* context = BuildContextChainWalk(variable);
2853 int index = variable->AsSlot()->index(); 2856 int index = variable->AsSlot()->index();
2854 HLoadContextSlot* instr = new HLoadContextSlot(context, index); 2857 HLoadContextSlot* instr = new HLoadContextSlot(context, index);
2855 ast_context()->ReturnInstruction(instr, expr->id()); 2858 ast_context()->ReturnInstruction(instr, expr->id());
2856 } else if (variable->is_global()) { 2859 } else if (variable->is_global()) {
2857 LookupResult lookup; 2860 LookupResult lookup;
2858 LookupGlobalPropertyCell(variable, &lookup, false); 2861 GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, false);
2859 CHECK_BAILOUT;
2860 2862
2861 Handle<GlobalObject> global(info()->global_object()); 2863 if (type == kUseCell &&
2862 // TODO(3039103): Handle global property load through an IC call when access 2864 info()->global_object()->IsAccessCheckNeeded()) {
2863 // checks are enabled. 2865 type = kUseGeneric;
2864 if (global->IsAccessCheckNeeded()) {
2865 BAILOUT("global object requires access check");
2866 } 2866 }
2867 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 2867
2868 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); 2868 if (type == kUseCell) {
2869 HLoadGlobal* instr = new HLoadGlobal(cell, check_hole); 2869 Handle<GlobalObject> global(info()->global_object());
2870 ast_context()->ReturnInstruction(instr, expr->id()); 2870 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
2871 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
2872 HLoadGlobalCell* instr = new HLoadGlobalCell(cell, check_hole);
2873 ast_context()->ReturnInstruction(instr, expr->id());
2874 } else {
2875 HContext* context = new HContext;
2876 AddInstruction(context);
2877 HGlobalObject* global_object = new HGlobalObject(context);
2878 AddInstruction(global_object);
2879 HLoadGlobalGeneric* instr =
2880 new HLoadGlobalGeneric(context,
2881 global_object,
2882 variable->name(),
2883 ast_context()->is_for_typeof());
2884 ast_context()->ReturnInstruction(instr, expr->id());
2885 }
2871 } else { 2886 } else {
2872 BAILOUT("reference to a variable which requires dynamic lookup"); 2887 BAILOUT("reference to a variable which requires dynamic lookup");
2873 } 2888 }
2874 } 2889 }
2875 2890
2876 2891
2877 void HGraphBuilder::VisitLiteral(Literal* expr) { 2892 void HGraphBuilder::VisitLiteral(Literal* expr) {
2878 HConstant* instr = new HConstant(expr->handle(), Representation::Tagged()); 2893 HConstant* instr = new HConstant(expr->handle(), Representation::Tagged());
2879 ast_context()->ReturnInstruction(instr, expr->id()); 2894 ast_context()->ReturnInstruction(instr, expr->id());
2880 } 2895 }
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
3217 3232
3218 3233
3219 // Because not every expression has a position and there is not common 3234 // Because not every expression has a position and there is not common
3220 // superclass of Assignment and CountOperation, we cannot just pass the 3235 // superclass of Assignment and CountOperation, we cannot just pass the
3221 // owning expression instead of position and ast_id separately. 3236 // owning expression instead of position and ast_id separately.
3222 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, 3237 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var,
3223 HValue* value, 3238 HValue* value,
3224 int position, 3239 int position,
3225 int ast_id) { 3240 int ast_id) {
3226 LookupResult lookup; 3241 LookupResult lookup;
3227 LookupGlobalPropertyCell(var, &lookup, true); 3242 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
3228 CHECK_BAILOUT; 3243 if (type == kUseCell) {
3229 3244 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
3230 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); 3245 Handle<GlobalObject> global(info()->global_object());
3231 Handle<GlobalObject> global(info()->global_object()); 3246 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
3232 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 3247 HInstruction* instr = new HStoreGlobal(value, cell, check_hole);
3233 HInstruction* instr = new HStoreGlobal(value, cell, check_hole); 3248 instr->set_position(position);
3234 instr->set_position(position); 3249 AddInstruction(instr);
3235 AddInstruction(instr); 3250 if (instr->HasSideEffects()) AddSimulate(ast_id);
3236 if (instr->HasSideEffects()) AddSimulate(ast_id); 3251 } else {
3252 BAILOUT("global store only supported for cells");
3253 }
3237 } 3254 }
3238 3255
3239 3256
3240 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 3257 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
3241 Expression* target = expr->target(); 3258 Expression* target = expr->target();
3242 VariableProxy* proxy = target->AsVariableProxy(); 3259 VariableProxy* proxy = target->AsVariableProxy();
3243 Variable* var = proxy->AsVariable(); 3260 Variable* var = proxy->AsVariable();
3244 Property* prop = target->AsProperty(); 3261 Property* prop = target->AsProperty();
3245 ASSERT(var == NULL || prop == NULL); 3262 ASSERT(var == NULL || prop == NULL);
3246 3263
(...skipping 1074 matching lines...) Expand 10 before | Expand all | Expand 10 after
4321 if (!global_call) { 4338 if (!global_call) {
4322 ++argument_count; 4339 ++argument_count;
4323 VISIT_FOR_VALUE(expr->expression()); 4340 VISIT_FOR_VALUE(expr->expression());
4324 } 4341 }
4325 4342
4326 if (global_call) { 4343 if (global_call) {
4327 bool known_global_function = false; 4344 bool known_global_function = false;
4328 // If there is a global property cell for the name at compile time and 4345 // 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 4346 // access check is not enabled we assume that the function will not change
4330 // and generate optimized code for calling the function. 4347 // and generate optimized code for calling the function.
4331 if (info()->has_global_object() && 4348 LookupResult lookup;
4349 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false);
4350 if (type == kUseCell &&
4332 !info()->global_object()->IsAccessCheckNeeded()) { 4351 !info()->global_object()->IsAccessCheckNeeded()) {
4333 Handle<GlobalObject> global(info()->global_object()); 4352 Handle<GlobalObject> global(info()->global_object());
4334 known_global_function = expr->ComputeGlobalTarget(global, var->name()); 4353 known_global_function = expr->ComputeGlobalTarget(global, &lookup);
4335 } 4354 }
4336 if (known_global_function) { 4355 if (known_global_function) {
4337 // Push the global object instead of the global receiver because 4356 // Push the global object instead of the global receiver because
4338 // code generated by the full code generator expects it. 4357 // code generated by the full code generator expects it.
4339 HContext* context = new HContext; 4358 HContext* context = new HContext;
4340 HGlobalObject* global_object = new HGlobalObject(context); 4359 HGlobalObject* global_object = new HGlobalObject(context);
4341 AddInstruction(context); 4360 AddInstruction(context);
4342 PushAndAdd(global_object); 4361 PushAndAdd(global_object);
4343 VisitExpressions(expr->arguments()); 4362 VisitExpressions(expr->arguments());
4344 CHECK_BAILOUT; 4363 CHECK_BAILOUT;
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
4543 break; 4562 break;
4544 case Token::SUB: 4563 case Token::SUB:
4545 instr = new HMul(graph_->GetConstantMinus1(), value); 4564 instr = new HMul(graph_->GetConstantMinus1(), value);
4546 break; 4565 break;
4547 default: 4566 default:
4548 UNREACHABLE(); 4567 UNREACHABLE();
4549 break; 4568 break;
4550 } 4569 }
4551 ast_context()->ReturnInstruction(instr, expr->id()); 4570 ast_context()->ReturnInstruction(instr, expr->id());
4552 } else if (op == Token::TYPEOF) { 4571 } else if (op == Token::TYPEOF) {
4553 VISIT_FOR_VALUE(expr->expression()); 4572 VisitForTypeOf(expr);
4573 if (HasStackOverflow()) return;
4554 HValue* value = Pop(); 4574 HValue* value = Pop();
4555 ast_context()->ReturnInstruction(new HTypeof(value), expr->id()); 4575 ast_context()->ReturnInstruction(new HTypeof(value), expr->id());
4556 } else { 4576 } else {
4557 BAILOUT("Value: unsupported unary operation"); 4577 BAILOUT("Value: unsupported unary operation");
4558 } 4578 }
4559 } 4579 }
4560 4580
4561 4581
4562 void HGraphBuilder::VisitIncrementOperation(IncrementOperation* expr) { 4582 void HGraphBuilder::VisitIncrementOperation(IncrementOperation* expr) {
4563 // IncrementOperation is never visited by the visitor. It only 4583 // 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()); 4948 ast_context()->ReturnInstruction(instr, expr->id());
4929 return; 4949 return;
4930 } 4950 }
4931 4951
4932 // Check for the pattern: typeof <expression> == <string literal>. 4952 // Check for the pattern: typeof <expression> == <string literal>.
4933 UnaryOperation* left_unary = expr->left()->AsUnaryOperation(); 4953 UnaryOperation* left_unary = expr->left()->AsUnaryOperation();
4934 Literal* right_literal = expr->right()->AsLiteral(); 4954 Literal* right_literal = expr->right()->AsLiteral();
4935 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) && 4955 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) &&
4936 left_unary != NULL && left_unary->op() == Token::TYPEOF && 4956 left_unary != NULL && left_unary->op() == Token::TYPEOF &&
4937 right_literal != NULL && right_literal->handle()->IsString()) { 4957 right_literal != NULL && right_literal->handle()->IsString()) {
4938 VISIT_FOR_VALUE(left_unary->expression()); 4958 VisitForTypeOf(expr);
4959 if (HasStackOverflow()) return;
4939 HValue* left = Pop(); 4960 HValue* left = Pop();
4940 HInstruction* instr = new HTypeofIs(left, 4961 HInstruction* instr = new HTypeofIs(left,
4941 Handle<String>::cast(right_literal->handle())); 4962 Handle<String>::cast(right_literal->handle()));
4942 instr->set_position(expr->position()); 4963 instr->set_position(expr->position());
4943 ast_context()->ReturnInstruction(instr, expr->id()); 4964 ast_context()->ReturnInstruction(instr, expr->id());
4944 return; 4965 return;
4945 } 4966 }
4946 4967
4947 VISIT_FOR_VALUE(expr->left()); 4968 VISIT_FOR_VALUE(expr->left());
4948 VISIT_FOR_VALUE(expr->right()); 4969 VISIT_FOR_VALUE(expr->right());
(...skipping 976 matching lines...) Expand 10 before | Expand all | Expand 10 after
5925 } 5946 }
5926 } 5947 }
5927 5948
5928 #ifdef DEBUG 5949 #ifdef DEBUG
5929 if (graph_ != NULL) graph_->Verify(); 5950 if (graph_ != NULL) graph_->Verify();
5930 if (allocator_ != NULL) allocator_->Verify(); 5951 if (allocator_ != NULL) allocator_->Verify();
5931 #endif 5952 #endif
5932 } 5953 }
5933 5954
5934 } } // namespace v8::internal 5955 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698