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

Side by Side Diff: src/hydrogen.cc

Issue 5550003: Add optimized compiler support for generic global loads.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years 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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 2095 matching lines...) Expand 10 before | Expand all | Expand 10 after
2106 // TODO(kasperl): Try to improve the way we compute the last added 2106 // TODO(kasperl): Try to improve the way we compute the last added
2107 // instruction. The NULL check makes me uncomfortable. 2107 // instruction. The NULL check makes me uncomfortable.
2108 HValue* last = subgraph()->exit_block()->GetLastInstruction(); 2108 HValue* last = subgraph()->exit_block()->GetLastInstruction();
2109 if (last != NULL && last->HasSideEffects()) { 2109 if (last != NULL && last->HasSideEffects()) {
2110 AddSimulate(expr->id()); 2110 AddSimulate(expr->id());
2111 } 2111 }
2112 ASSERT(environment()->values()->length() == original_height + 1); 2112 ASSERT(environment()->values()->length() == original_height + 1);
2113 } 2113 }
2114 2114
2115 2115
2116 void HGraphBuilder::VisitForTypeofValue(Expression* expr) {
Kevin Millikin (Chromium) 2010/12/09 13:16:51 It seems to me that "parent is typeof" is just a f
fschneider 2010/12/22 16:02:34 Done.
2117 VariableProxy* proxy = expr->AsVariableProxy();
2118 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
Kevin Millikin (Chromium) 2010/12/09 13:16:51 I think you can just ask the proxy is_this (and ma
fschneider 2010/12/22 16:02:34 Done. This part of the code is now gone.
2119 #ifdef DEBUG
2120 int original_height = environment()->values()->length();
2121 #endif
2122 HandleGlobalVariableLoad(proxy, true); // Inside typeof.
2123 // Generic global loads always have a side effect.
2124 AddSimulate(expr->id());
2125 ASSERT(environment()->values()->length() == original_height + 1);
2126 } else {
2127 VisitForValue(expr);
2128 }
2129 }
2130
2131
2116 HValue* HGraphBuilder::VisitArgument(Expression* expr) { 2132 HValue* HGraphBuilder::VisitArgument(Expression* expr) {
2117 VisitForValue(expr); 2133 VisitForValue(expr);
2118 if (HasStackOverflow() || !subgraph()->HasExit()) return NULL; 2134 if (HasStackOverflow() || !subgraph()->HasExit()) return NULL;
2119 return environment()->Top(); 2135 return environment()->Top();
2120 } 2136 }
2121 2137
2122 2138
2123 void HGraphBuilder::VisitArgumentList(ZoneList<Expression*>* arguments) { 2139 void HGraphBuilder::VisitArgumentList(ZoneList<Expression*>* arguments) {
2124 for (int i = 0; i < arguments->length(); i++) { 2140 for (int i = 0; i < arguments->length(); i++) {
2125 VisitArgument(arguments->at(i)); 2141 VisitArgument(arguments->at(i));
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after
2931 then_graph->entry_block(), 2947 then_graph->entry_block(),
2932 else_graph->entry_block(), 2948 else_graph->entry_block(),
2933 false, false); 2949 false, false);
2934 if (HasStackOverflow()) return; 2950 if (HasStackOverflow()) return;
2935 ADD_TO_SUBGRAPH(then_graph, expr->then_expression()); 2951 ADD_TO_SUBGRAPH(then_graph, expr->then_expression());
2936 ADD_TO_SUBGRAPH(else_graph, expr->else_expression()); 2952 ADD_TO_SUBGRAPH(else_graph, expr->else_expression());
2937 current_subgraph_->AppendJoin(then_graph, else_graph, expr); 2953 current_subgraph_->AppendJoin(then_graph, else_graph, expr);
2938 } 2954 }
2939 2955
2940 2956
2941 void HGraphBuilder::LookupGlobalPropertyCell(VariableProxy* expr, 2957 void HGraphBuilder::LookupGlobalPropertyCell(VariableProxy* expr,
Kevin Millikin (Chromium) 2010/12/09 13:16:51 It seems like it would be cleaner for this functio
fschneider 2010/12/22 16:02:34 I wanted to be able to use the BAILOUT macro from
2942 LookupResult* lookup, 2958 LookupResult* lookup,
2943 bool is_store) { 2959 bool is_store,
2960 bool* is_generic) {
2961 *is_generic = true;
2944 if (expr->is_this()) { 2962 if (expr->is_this()) {
2945 BAILOUT("global this reference"); 2963 BAILOUT("global this reference");
2946 } 2964 }
2947 if (!graph()->info()->has_global_object()) { 2965 if (!graph()->info()->has_global_object()) {
2948 BAILOUT("no global object to optimize VariableProxy"); 2966 BAILOUT("no global object to optimize VariableProxy");
2949 } 2967 }
2950 Handle<GlobalObject> global(graph()->info()->global_object()); 2968 Handle<GlobalObject> global(graph()->info()->global_object());
2951 global->Lookup(*expr->name(), lookup); 2969 global->Lookup(*expr->name(), lookup);
2952 if (!lookup->IsProperty()) { 2970 if (!lookup->IsProperty()) return;
2953 BAILOUT("global variable cell not yet introduced"); 2971 if (lookup->type() != NORMAL) return;
2972 if (is_store && lookup->IsReadOnly()) {
2973 BAILOUT("store to read-only global variable");
2954 } 2974 }
2955 if (lookup->type() != NORMAL) { 2975 *is_generic = false;
2956 BAILOUT("global variable has accessors"); 2976 }
2957 } 2977
2958 if (is_store && lookup->IsReadOnly()) { 2978
2959 BAILOUT("read-only global variable"); 2979 void HGraphBuilder::HandleGlobalVariableLoad(VariableProxy* expr,
Kevin Millikin (Chromium) 2010/12/09 13:16:51 We need to restore some sanity to these helper fun
fschneider 2010/12/22 16:02:34 Done.
2980 bool inside_typeof) {
2981 LookupResult lookup;
2982 bool is_generic = true;
2983 LookupGlobalPropertyCell(expr, &lookup, false, &is_generic);
2984 CHECK_BAILOUT;
2985
2986 Handle<GlobalObject> global(graph()->info()->global_object());
2987 if (is_generic || global->IsAccessCheckNeeded()) {
2988 PushAndAdd(new HLoadGlobalGeneric(expr->var()->name(), inside_typeof));
Kevin Millikin (Chromium) 2010/12/09 13:16:51 Here you could just ask the ast_context if it is a
fschneider 2010/12/22 16:02:34 Done.
2989 } else {
2990 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
2991 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
2992 PushAndAdd(new HLoadGlobal(cell, check_hole));
2960 } 2993 }
2961 } 2994 }
2962 2995
2963 2996
2964 void HGraphBuilder::HandleGlobalVariableLoad(VariableProxy* expr) {
2965 LookupResult lookup;
2966 LookupGlobalPropertyCell(expr, &lookup, false);
2967 CHECK_BAILOUT;
2968
2969 Handle<GlobalObject> global(graph()->info()->global_object());
2970 // TODO(3039103): Handle global property load through an IC call when access
2971 // checks are enabled.
2972 if (global->IsAccessCheckNeeded()) {
2973 BAILOUT("global object requires access check");
2974 }
2975 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
2976 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
2977 PushAndAdd(new HLoadGlobal(cell, check_hole));
2978 }
2979
2980
2981 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 2997 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
2982 Variable* variable = expr->AsVariable(); 2998 Variable* variable = expr->AsVariable();
2983 if (variable == NULL) { 2999 if (variable == NULL) {
2984 BAILOUT("reference to rewritten variable"); 3000 BAILOUT("reference to rewritten variable");
2985 } else if (variable->IsStackAllocated()) { 3001 } else if (variable->IsStackAllocated()) {
2986 if (environment()->Lookup(variable)->CheckFlag(HValue::kIsArguments)) { 3002 if (environment()->Lookup(variable)->CheckFlag(HValue::kIsArguments)) {
2987 BAILOUT("unsupported context for arguments object"); 3003 BAILOUT("unsupported context for arguments object");
2988 } 3004 }
2989 Push(environment()->Lookup(variable)); 3005 Push(environment()->Lookup(variable));
2990 } else if (variable->is_global()) { 3006 } else if (variable->is_global()) {
2991 HandleGlobalVariableLoad(expr); 3007 HandleGlobalVariableLoad(expr, false); // Not inside typeof.
2992 } else { 3008 } else {
2993 BAILOUT("reference to non-stack-allocated/non-global variable"); 3009 BAILOUT("reference to non-stack-allocated/non-global variable");
2994 } 3010 }
2995 } 3011 }
2996 3012
2997 3013
2998 void HGraphBuilder::VisitLiteral(Literal* expr) { 3014 void HGraphBuilder::VisitLiteral(Literal* expr) {
2999 PushAndAdd(new HConstant(expr->handle(), Representation::Tagged())); 3015 PushAndAdd(new HConstant(expr->handle(), Representation::Tagged()));
3000 } 3016 }
3001 3017
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
3333 Push(value); 3349 Push(value);
3334 instr->set_position(expr->position()); 3350 instr->set_position(expr->position());
3335 AddInstruction(instr); 3351 AddInstruction(instr);
3336 } 3352 }
3337 3353
3338 3354
3339 void HGraphBuilder::HandleGlobalVariableAssignment(VariableProxy* proxy, 3355 void HGraphBuilder::HandleGlobalVariableAssignment(VariableProxy* proxy,
3340 HValue* value, 3356 HValue* value,
3341 int position) { 3357 int position) {
3342 LookupResult lookup; 3358 LookupResult lookup;
3343 LookupGlobalPropertyCell(proxy, &lookup, true); 3359 bool is_generic;
3360 LookupGlobalPropertyCell(proxy, &lookup, true, &is_generic);
3344 CHECK_BAILOUT; 3361 CHECK_BAILOUT;
3345 3362
3346 Handle<GlobalObject> global(graph()->info()->global_object()); 3363 Handle<GlobalObject> global(graph()->info()->global_object());
3347 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 3364 if (!is_generic && !global->IsAccessCheckNeeded()) {
3348 HInstruction* instr = new HStoreGlobal(value, cell); 3365 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
3349 instr->set_position(position); 3366 HInstruction* instr = new HStoreGlobal(value, cell);
3350 AddInstruction(instr); 3367 instr->set_position(position);
3368 AddInstruction(instr);
3369 } else {
3370 BAILOUT("unsupported store to global");
3371 }
3351 } 3372 }
3352 3373
3353 3374
3354 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 3375 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
3355 Expression* target = expr->target(); 3376 Expression* target = expr->target();
3356 VariableProxy* proxy = target->AsVariableProxy(); 3377 VariableProxy* proxy = target->AsVariableProxy();
3357 Variable* var = proxy->AsVariable(); 3378 Variable* var = proxy->AsVariable();
3358 Property* prop = target->AsProperty(); 3379 Property* prop = target->AsProperty();
3359 ASSERT(var == NULL || prop == NULL); 3380 ASSERT(var == NULL || prop == NULL);
3360 3381
(...skipping 1032 matching lines...) Expand 10 before | Expand all | Expand 10 after
4393 break; 4414 break;
4394 case Token::SUB: 4415 case Token::SUB:
4395 instr = new HMul(graph_->GetConstantMinus1(), value); 4416 instr = new HMul(graph_->GetConstantMinus1(), value);
4396 break; 4417 break;
4397 default: 4418 default:
4398 UNREACHABLE(); 4419 UNREACHABLE();
4399 break; 4420 break;
4400 } 4421 }
4401 PushAndAdd(instr); 4422 PushAndAdd(instr);
4402 } else if (op == Token::TYPEOF) { 4423 } else if (op == Token::TYPEOF) {
4403 VISIT_FOR_VALUE(expr->expression()); 4424 VisitForTypeofValue(expr->expression());
4425 if (HasStackOverflow()) return;
4404 HValue* value = Pop(); 4426 HValue* value = Pop();
4405 PushAndAdd(new HTypeof(value)); 4427 PushAndAdd(new HTypeof(value));
4406 } else { 4428 } else {
4407 BAILOUT("Value: unsupported unary operation"); 4429 BAILOUT("Value: unsupported unary operation");
4408 } 4430 }
4409 } 4431 }
4410 4432
4411 4433
4412 void HGraphBuilder::VisitIncrementOperation(IncrementOperation* expr) { 4434 void HGraphBuilder::VisitIncrementOperation(IncrementOperation* expr) {
4413 // IncrementOperation is never visited by the visitor. It only 4435 // IncrementOperation is never visited by the visitor. It only
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
4694 PushAndAdd(instr, expr->position()); 4716 PushAndAdd(instr, expr->position());
4695 return; 4717 return;
4696 } 4718 }
4697 4719
4698 // Check for the pattern: typeof <expression> == <string literal>. 4720 // Check for the pattern: typeof <expression> == <string literal>.
4699 UnaryOperation* left_unary = expr->left()->AsUnaryOperation(); 4721 UnaryOperation* left_unary = expr->left()->AsUnaryOperation();
4700 Literal* right_literal = expr->right()->AsLiteral(); 4722 Literal* right_literal = expr->right()->AsLiteral();
4701 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) && 4723 if ((expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT) &&
4702 left_unary != NULL && left_unary->op() == Token::TYPEOF && 4724 left_unary != NULL && left_unary->op() == Token::TYPEOF &&
4703 right_literal != NULL && right_literal->handle()->IsString()) { 4725 right_literal != NULL && right_literal->handle()->IsString()) {
4704 VISIT_FOR_VALUE(left_unary->expression()); 4726 VisitForTypeofValue(left_unary->expression());
4727 if (HasStackOverflow()) return;
4705 HValue* left = Pop(); 4728 HValue* left = Pop();
4706 HInstruction* instr = new HTypeofIs(left, 4729 HInstruction* instr = new HTypeofIs(left,
4707 Handle<String>::cast(right_literal->handle())); 4730 Handle<String>::cast(right_literal->handle()));
4708 PushAndAdd(instr, expr->position()); 4731 PushAndAdd(instr, expr->position());
4709 return; 4732 return;
4710 } 4733 }
4711 4734
4712 VISIT_FOR_VALUE(expr->left()); 4735 VISIT_FOR_VALUE(expr->left());
4713 VISIT_FOR_VALUE(expr->right()); 4736 VISIT_FOR_VALUE(expr->right());
4714 4737
(...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after
5541 } 5564 }
5542 5565
5543 #ifdef DEBUG 5566 #ifdef DEBUG
5544 if (graph_ != NULL) graph_->Verify(); 5567 if (graph_ != NULL) graph_->Verify();
5545 if (chunk_ != NULL) chunk_->Verify(); 5568 if (chunk_ != NULL) chunk_->Verify();
5546 if (allocator_ != NULL) allocator_->Verify(); 5569 if (allocator_ != NULL) allocator_->Verify();
5547 #endif 5570 #endif
5548 } 5571 }
5549 5572
5550 } } // namespace v8::internal 5573 } } // 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