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

Side by Side Diff: src/hydrogen.cc

Issue 6758007: Increase coverage of global loads in optimized code (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 8 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 1962 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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 689 matching lines...) Expand 10 before | Expand all | Expand 10 after
2826 CHECK_BAILOUT; 2837 CHECK_BAILOUT;
2827 2838
2828 if (!ast_context()->IsTest()) { 2839 if (!ast_context()->IsTest()) {
2829 HBasicBlock* join = CreateJoin(other, current_block(), expr->id()); 2840 HBasicBlock* join = CreateJoin(other, current_block(), expr->id());
2830 set_current_block(join); 2841 set_current_block(join);
2831 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 2842 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
2832 } 2843 }
2833 } 2844 }
2834 2845
2835 2846
2836 void HGraphBuilder::LookupGlobalPropertyCell(Variable* var, 2847 HGraphBuilder::GlobalPropertyAccess HGraphBuilder::LookupGlobalProperty(
2837 LookupResult* lookup, 2848 Variable* var, LookupResult* lookup, bool is_store) {
2838 bool is_store) { 2849 if (var->is_this() || !info()->has_global_object()) {
2839 if (var->is_this()) { 2850 return kUseGeneric;
2840 BAILOUT("global this reference");
2841 }
2842 if (!info()->has_global_object()) {
2843 BAILOUT("no global object to optimize VariableProxy");
2844 } 2851 }
2845 Handle<GlobalObject> global(info()->global_object()); 2852 Handle<GlobalObject> global(info()->global_object());
2846 global->Lookup(*var->name(), lookup); 2853 global->Lookup(*var->name(), lookup);
2847 if (!lookup->IsProperty()) { 2854 if (!lookup->IsProperty() ||
2848 BAILOUT("global variable cell not yet introduced"); 2855 lookup->type() != NORMAL ||
2856 (is_store && lookup->IsReadOnly()) ||
2857 lookup->holder() != *global) {
2858 return kUseGeneric;
2849 } 2859 }
2850 if (lookup->type() != NORMAL) { 2860
2851 BAILOUT("global variable has accessors"); 2861 return kUseCell;
2852 }
2853 if (is_store && lookup->IsReadOnly()) {
2854 BAILOUT("read-only global variable");
2855 }
2856 if (lookup->holder() != *global) {
2857 BAILOUT("global property on prototype of global object");
2858 }
2859 } 2862 }
2860 2863
2861 2864
2862 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) { 2865 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) {
2863 ASSERT(var->IsContextSlot()); 2866 ASSERT(var->IsContextSlot());
2864 HInstruction* context = new HContext; 2867 HInstruction* context = new HContext;
2865 AddInstruction(context); 2868 AddInstruction(context);
2866 int length = info()->scope()->ContextChainLength(var->scope()); 2869 int length = info()->scope()->ContextChainLength(var->scope());
2867 while (length-- > 0) { 2870 while (length-- > 0) {
2868 context = new HOuterContext(context); 2871 context = new HOuterContext(context);
(...skipping 15 matching lines...) Expand all
2884 } else if (variable->IsContextSlot()) { 2887 } else if (variable->IsContextSlot()) {
2885 if (variable->mode() == Variable::CONST) { 2888 if (variable->mode() == Variable::CONST) {
2886 BAILOUT("reference to const context slot"); 2889 BAILOUT("reference to const context slot");
2887 } 2890 }
2888 HValue* context = BuildContextChainWalk(variable); 2891 HValue* context = BuildContextChainWalk(variable);
2889 int index = variable->AsSlot()->index(); 2892 int index = variable->AsSlot()->index();
2890 HLoadContextSlot* instr = new HLoadContextSlot(context, index); 2893 HLoadContextSlot* instr = new HLoadContextSlot(context, index);
2891 ast_context()->ReturnInstruction(instr, expr->id()); 2894 ast_context()->ReturnInstruction(instr, expr->id());
2892 } else if (variable->is_global()) { 2895 } else if (variable->is_global()) {
2893 LookupResult lookup; 2896 LookupResult lookup;
2894 LookupGlobalPropertyCell(variable, &lookup, false); 2897 GlobalPropertyAccess type = LookupGlobalProperty(variable, &lookup, false);
2895 CHECK_BAILOUT;
2896 2898
2897 Handle<GlobalObject> global(info()->global_object()); 2899 if (type == kUseCell &&
2898 // TODO(3039103): Handle global property load through an IC call when access 2900 info()->global_object()->IsAccessCheckNeeded()) {
2899 // checks are enabled. 2901 type = kUseGeneric;
2900 if (global->IsAccessCheckNeeded()) {
2901 BAILOUT("global object requires access check");
2902 } 2902 }
2903 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 2903
2904 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); 2904 if (type == kUseCell) {
2905 HLoadGlobal* instr = new HLoadGlobal(cell, check_hole); 2905 Handle<GlobalObject> global(info()->global_object());
2906 ast_context()->ReturnInstruction(instr, expr->id()); 2906 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
2907 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
2908 HLoadGlobalCell* instr = new HLoadGlobalCell(cell, check_hole);
2909 ast_context()->ReturnInstruction(instr, expr->id());
2910 } else {
2911 HContext* context = new HContext;
2912 AddInstruction(context);
2913 HGlobalObject* global_object = new HGlobalObject(context);
2914 AddInstruction(global_object);
2915 HLoadGlobalGeneric* instr =
2916 new HLoadGlobalGeneric(context,
2917 global_object,
2918 variable->name(),
2919 ast_context()->is_for_typeof());
2920 instr->set_position(expr->position());
2921 ASSERT(instr->HasSideEffects());
2922 ast_context()->ReturnInstruction(instr, expr->id());
2923 }
2907 } else { 2924 } else {
2908 BAILOUT("reference to a variable which requires dynamic lookup"); 2925 BAILOUT("reference to a variable which requires dynamic lookup");
2909 } 2926 }
2910 } 2927 }
2911 2928
2912 2929
2913 void HGraphBuilder::VisitLiteral(Literal* expr) { 2930 void HGraphBuilder::VisitLiteral(Literal* expr) {
2914 HConstant* instr = new HConstant(expr->handle(), Representation::Tagged()); 2931 HConstant* instr = new HConstant(expr->handle(), Representation::Tagged());
2915 ast_context()->ReturnInstruction(instr, expr->id()); 2932 ast_context()->ReturnInstruction(instr, expr->id());
2916 } 2933 }
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
3267 3284
3268 3285
3269 // Because not every expression has a position and there is not common 3286 // Because not every expression has a position and there is not common
3270 // superclass of Assignment and CountOperation, we cannot just pass the 3287 // superclass of Assignment and CountOperation, we cannot just pass the
3271 // owning expression instead of position and ast_id separately. 3288 // owning expression instead of position and ast_id separately.
3272 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, 3289 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var,
3273 HValue* value, 3290 HValue* value,
3274 int position, 3291 int position,
3275 int ast_id) { 3292 int ast_id) {
3276 LookupResult lookup; 3293 LookupResult lookup;
3277 LookupGlobalPropertyCell(var, &lookup, true); 3294 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, true);
3278 CHECK_BAILOUT; 3295 if (type == kUseCell) {
3279 3296 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
3280 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly(); 3297 Handle<GlobalObject> global(info()->global_object());
3281 Handle<GlobalObject> global(info()->global_object()); 3298 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
3282 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 3299 HInstruction* instr = new HStoreGlobal(value, cell, check_hole);
3283 HInstruction* instr = new HStoreGlobal(value, cell, check_hole); 3300 instr->set_position(position);
3284 instr->set_position(position); 3301 AddInstruction(instr);
3285 AddInstruction(instr); 3302 if (instr->HasSideEffects()) AddSimulate(ast_id);
3286 if (instr->HasSideEffects()) AddSimulate(ast_id); 3303 } else {
3304 BAILOUT("global store only supported for cells");
3305 }
3287 } 3306 }
3288 3307
3289 3308
3290 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 3309 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
3291 Expression* target = expr->target(); 3310 Expression* target = expr->target();
3292 VariableProxy* proxy = target->AsVariableProxy(); 3311 VariableProxy* proxy = target->AsVariableProxy();
3293 Variable* var = proxy->AsVariable(); 3312 Variable* var = proxy->AsVariable();
3294 Property* prop = target->AsProperty(); 3313 Property* prop = target->AsProperty();
3295 ASSERT(var == NULL || prop == NULL); 3314 ASSERT(var == NULL || prop == NULL);
3296 3315
(...skipping 1007 matching lines...) Expand 10 before | Expand all | Expand 10 after
4304 if (!global_call) { 4323 if (!global_call) {
4305 ++argument_count; 4324 ++argument_count;
4306 VISIT_FOR_VALUE(expr->expression()); 4325 VISIT_FOR_VALUE(expr->expression());
4307 } 4326 }
4308 4327
4309 if (global_call) { 4328 if (global_call) {
4310 bool known_global_function = false; 4329 bool known_global_function = false;
4311 // If there is a global property cell for the name at compile time and 4330 // If there is a global property cell for the name at compile time and
4312 // access check is not enabled we assume that the function will not change 4331 // access check is not enabled we assume that the function will not change
4313 // and generate optimized code for calling the function. 4332 // and generate optimized code for calling the function.
4314 if (info()->has_global_object() && 4333 LookupResult lookup;
4334 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false);
4335 if (type == kUseCell &&
4315 !info()->global_object()->IsAccessCheckNeeded()) { 4336 !info()->global_object()->IsAccessCheckNeeded()) {
4316 Handle<GlobalObject> global(info()->global_object()); 4337 Handle<GlobalObject> global(info()->global_object());
4317 known_global_function = expr->ComputeGlobalTarget(global, var->name()); 4338 known_global_function = expr->ComputeGlobalTarget(global, &lookup);
4318 } 4339 }
4319 if (known_global_function) { 4340 if (known_global_function) {
4320 // Push the global object instead of the global receiver because 4341 // Push the global object instead of the global receiver because
4321 // code generated by the full code generator expects it. 4342 // code generated by the full code generator expects it.
4322 HContext* context = new HContext; 4343 HContext* context = new HContext;
4323 HGlobalObject* global_object = new HGlobalObject(context); 4344 HGlobalObject* global_object = new HGlobalObject(context);
4324 AddInstruction(context); 4345 AddInstruction(context);
4325 PushAndAdd(global_object); 4346 PushAndAdd(global_object);
4326 VisitExpressions(expr->arguments()); 4347 VisitExpressions(expr->arguments());
4327 CHECK_BAILOUT; 4348 CHECK_BAILOUT;
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
4510 HBasicBlock* join = 4531 HBasicBlock* join =
4511 CreateJoin(materialize_false, materialize_true, expr->id()); 4532 CreateJoin(materialize_false, materialize_true, expr->id());
4512 set_current_block(join); 4533 set_current_block(join);
4513 ast_context()->ReturnValue(Pop()); 4534 ast_context()->ReturnValue(Pop());
4514 } else { 4535 } else {
4515 ASSERT(ast_context()->IsEffect()); 4536 ASSERT(ast_context()->IsEffect());
4516 VisitForEffect(expr->expression()); 4537 VisitForEffect(expr->expression());
4517 } 4538 }
4518 4539
4519 } else if (op == Token::TYPEOF) { 4540 } else if (op == Token::TYPEOF) {
4520 VISIT_FOR_VALUE(expr->expression()); 4541 VisitForTypeOf(expr->expression());
4542 if (HasStackOverflow()) return;
4521 HValue* value = Pop(); 4543 HValue* value = Pop();
4522 ast_context()->ReturnInstruction(new HTypeof(value), expr->id()); 4544 ast_context()->ReturnInstruction(new HTypeof(value), expr->id());
4523 4545
4524 } else { 4546 } else {
4525 VISIT_FOR_VALUE(expr->expression()); 4547 VISIT_FOR_VALUE(expr->expression());
4526 HValue* value = Pop(); 4548 HValue* value = Pop();
4527 HInstruction* instr = NULL; 4549 HInstruction* instr = NULL;
4528 switch (op) { 4550 switch (op) {
4529 case Token::BIT_NOT: 4551 case Token::BIT_NOT:
4530 instr = new HBitNot(value); 4552 instr = new HBitNot(value);
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
4913 ast_context()->ReturnInstruction(instr, expr->id()); 4935 ast_context()->ReturnInstruction(instr, expr->id());
4914 return; 4936 return;
4915 } 4937 }
4916 4938
4917 // Check for the pattern: typeof <expression> == <string literal>. 4939 // Check for the pattern: typeof <expression> == <string literal>.
4918 UnaryOperation* left_unary = expr->left()->AsUnaryOperation(); 4940 UnaryOperation* left_unary = expr->left()->AsUnaryOperation();
4919 Literal* right_literal = expr->right()->AsLiteral(); 4941 Literal* right_literal = expr->right()->AsLiteral();
4920 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) && 4942 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) &&
4921 left_unary != NULL && left_unary->op() == Token::TYPEOF && 4943 left_unary != NULL && left_unary->op() == Token::TYPEOF &&
4922 right_literal != NULL && right_literal->handle()->IsString()) { 4944 right_literal != NULL && right_literal->handle()->IsString()) {
4923 VISIT_FOR_VALUE(left_unary->expression()); 4945 VisitForTypeOf(left_unary->expression());
4946 if (HasStackOverflow()) return;
4924 HValue* left = Pop(); 4947 HValue* left = Pop();
4925 HInstruction* instr = new HTypeofIs(left, 4948 HInstruction* instr = new HTypeofIs(left,
4926 Handle<String>::cast(right_literal->handle())); 4949 Handle<String>::cast(right_literal->handle()));
4927 instr->set_position(expr->position()); 4950 instr->set_position(expr->position());
4928 ast_context()->ReturnInstruction(instr, expr->id()); 4951 ast_context()->ReturnInstruction(instr, expr->id());
4929 return; 4952 return;
4930 } 4953 }
4931 4954
4932 VISIT_FOR_VALUE(expr->left()); 4955 VISIT_FOR_VALUE(expr->left());
4933 VISIT_FOR_VALUE(expr->right()); 4956 VISIT_FOR_VALUE(expr->right());
(...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after
5915 } 5938 }
5916 } 5939 }
5917 5940
5918 #ifdef DEBUG 5941 #ifdef DEBUG
5919 if (graph_ != NULL) graph_->Verify(); 5942 if (graph_ != NULL) graph_->Verify();
5920 if (allocator_ != NULL) allocator_->Verify(); 5943 if (allocator_ != NULL) allocator_->Verify();
5921 #endif 5944 #endif
5922 } 5945 }
5923 5946
5924 } } // namespace v8::internal 5947 } } // namespace v8::internal
OLDNEW
« src/ast.cc ('K') | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698