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

Side by Side Diff: src/hydrogen.cc

Issue 192513002: Checking for stack height equality between full codegen and hydrogen. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase Created 6 years, 7 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/ia32/full-codegen-ia32.cc » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "hydrogen.h" 5 #include "hydrogen.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "v8.h" 9 #include "v8.h"
10 #include "allocation-site-scopes.h" 10 #include "allocation-site-scopes.h"
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 HPhi* HBasicBlock::AddNewPhi(int merged_index) { 150 HPhi* HBasicBlock::AddNewPhi(int merged_index) {
151 if (graph()->IsInsideNoSideEffectsScope()) { 151 if (graph()->IsInsideNoSideEffectsScope()) {
152 merged_index = HPhi::kInvalidMergedIndex; 152 merged_index = HPhi::kInvalidMergedIndex;
153 } 153 }
154 HPhi* phi = new(zone()) HPhi(merged_index, zone()); 154 HPhi* phi = new(zone()) HPhi(merged_index, zone());
155 AddPhi(phi); 155 AddPhi(phi);
156 return phi; 156 return phi;
157 } 157 }
158 158
159 159
160 HSimulate* HBasicBlock::AddNewSimulate(
161 BailoutId ast_id,
162 HSourcePosition position,
163 RemovableSimulate removable,
164 int arguments_offset) {
165 HSimulate* instr = CreateSimulate(ast_id, removable, arguments_offset);
166 AddInstruction(instr, position);
167 return instr;
168 }
169
170
160 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, 171 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id,
161 RemovableSimulate removable) { 172 RemovableSimulate removable,
173 int arguments_offset) {
162 ASSERT(HasEnvironment()); 174 ASSERT(HasEnvironment());
163 HEnvironment* environment = last_environment(); 175 HEnvironment* environment = last_environment();
164 ASSERT(ast_id.IsNone() || 176 ASSERT(ast_id.IsNone() ||
165 ast_id == BailoutId::StubEntry() || 177 ast_id == BailoutId::StubEntry() ||
166 environment->closure()->shared()->VerifyBailoutId(ast_id)); 178 environment->closure()->shared()->VerifyBailoutId(ast_id));
167 179
168 int push_count = environment->push_count(); 180 int push_count = environment->push_count();
169 int pop_count = environment->pop_count(); 181 int pop_count = environment->pop_count();
170 182
171 HSimulate* instr = 183 HSimulate* instr =
172 new(zone()) HSimulate(ast_id, pop_count, zone(), removable); 184 new(zone()) HSimulate(ast_id, pop_count, zone(), removable);
173 #ifdef DEBUG 185 #ifdef DEBUG
174 instr->set_closure(environment->closure()); 186 instr->set_closure(environment->closure());
175 #endif 187 #endif
176 // Order of pushed values: newest (top of stack) first. This allows 188 // Order of pushed values: newest (top of stack) first. This allows
177 // HSimulate::MergeWith() to easily append additional pushed values 189 // HSimulate::MergeWith() to easily append additional pushed values
178 // that are older (from further down the stack). 190 // that are older (from further down the stack).
179 for (int i = 0; i < push_count; ++i) { 191 for (int i = 0; i < push_count; ++i) {
180 instr->AddPushedValue(environment->ExpressionStackAt(i)); 192 instr->AddPushedValue(environment->ExpressionStackAt(i));
181 } 193 }
182 for (GrowableBitVector::Iterator it(environment->assigned_variables(), 194 for (GrowableBitVector::Iterator it(environment->assigned_variables(),
183 zone()); 195 zone());
184 !it.Done(); 196 !it.Done();
185 it.Advance()) { 197 it.Advance()) {
186 int index = it.Current(); 198 int index = it.Current();
187 instr->AddAssignedValue(index, environment->Lookup(index)); 199 instr->AddAssignedValue(index, environment->Lookup(index));
188 } 200 }
189 environment->ClearHistory(); 201 environment->ClearHistory();
202 #if defined(COMPARE_OPT_STACK_HEIGHT)
203 environment->VerifyStackHeight(
204 ast_id, instr->id(), arguments_offset);
205 #endif
190 return instr; 206 return instr;
191 } 207 }
192 208
193 209
194 void HBasicBlock::Finish(HControlInstruction* end, HSourcePosition position) { 210 void HBasicBlock::Finish(HControlInstruction* end, HSourcePosition position) {
195 ASSERT(!IsFinished()); 211 ASSERT(!IsFinished());
196 AddInstruction(end, position); 212 AddInstruction(end, position);
197 end_ = end; 213 end_ = end;
198 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { 214 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) {
199 it.Current()->RegisterPredecessor(this); 215 it.Current()->RegisterPredecessor(this);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 UpdateEnvironment(env); 265 UpdateEnvironment(env);
250 } 266 }
251 267
252 268
253 void HBasicBlock::UpdateEnvironment(HEnvironment* env) { 269 void HBasicBlock::UpdateEnvironment(HEnvironment* env) {
254 last_environment_ = env; 270 last_environment_ = env;
255 graph()->update_maximum_environment_size(env->first_expression_index()); 271 graph()->update_maximum_environment_size(env->first_expression_index());
256 } 272 }
257 273
258 274
259 void HBasicBlock::SetJoinId(BailoutId ast_id) { 275 void HBasicBlock::SetJoinId(BailoutId ast_id, int stack_check_offset) {
260 int length = predecessors_.length(); 276 int length = predecessors_.length();
261 ASSERT(length > 0); 277 ASSERT(length > 0);
262 for (int i = 0; i < length; i++) { 278 for (int i = 0; i < length; i++) {
263 HBasicBlock* predecessor = predecessors_[i]; 279 HBasicBlock* predecessor = predecessors_[i];
264 ASSERT(predecessor->end()->IsGoto()); 280 ASSERT(predecessor->end()->IsGoto());
265 HSimulate* simulate = HSimulate::cast(predecessor->end()->previous()); 281 HSimulate* simulate = HSimulate::cast(predecessor->end()->previous());
266 ASSERT(i != 0 || 282 ASSERT(i != 0 ||
267 (predecessor->last_environment()->closure().is_null() || 283 (predecessor->last_environment()->closure().is_null() ||
268 predecessor->last_environment()->closure()->shared() 284 predecessor->last_environment()->closure()->shared()
269 ->VerifyBailoutId(ast_id))); 285 ->VerifyBailoutId(ast_id)));
270 simulate->set_ast_id(ast_id); 286 simulate->set_ast_id(ast_id);
287 #if defined(COMPARE_OPT_STACK_HEIGHT)
288 predecessor->last_environment()->VerifyStackHeight(
289 ast_id, simulate->id(), stack_check_offset);
290 #endif
271 predecessor->last_environment()->set_ast_id(ast_id); 291 predecessor->last_environment()->set_ast_id(ast_id);
272 } 292 }
273 } 293 }
274 294
275 295
276 bool HBasicBlock::Dominates(HBasicBlock* other) const { 296 bool HBasicBlock::Dominates(HBasicBlock* other) const {
277 HBasicBlock* current = other->dominator(); 297 HBasicBlock* current = other->dominator();
278 while (current != NULL) { 298 while (current != NULL) {
279 if (current == this) return true; 299 if (current == this) return true;
280 current = current->dominator(); 300 current = current->dominator();
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after
1198 reference, static_cast<HValue*>(NULL), HObjectAccess::ForCounter()); 1218 reference, static_cast<HValue*>(NULL), HObjectAccess::ForCounter());
1199 HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1()); 1219 HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1());
1200 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow 1220 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow
1201 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), 1221 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(),
1202 new_value, STORE_TO_INITIALIZED_ENTRY); 1222 new_value, STORE_TO_INITIALIZED_ENTRY);
1203 } 1223 }
1204 } 1224 }
1205 1225
1206 1226
1207 void HGraphBuilder::AddSimulate(BailoutId id, 1227 void HGraphBuilder::AddSimulate(BailoutId id,
1208 RemovableSimulate removable) { 1228 RemovableSimulate removable,
1229 int arguments_offset) {
1209 ASSERT(current_block() != NULL); 1230 ASSERT(current_block() != NULL);
1210 ASSERT(!graph()->IsInsideNoSideEffectsScope()); 1231 ASSERT(!graph()->IsInsideNoSideEffectsScope());
1211 current_block()->AddNewSimulate(id, source_position(), removable); 1232 current_block()->AddNewSimulate(
1233 id, source_position(), removable, arguments_offset);
1212 } 1234 }
1213 1235
1214 1236
1215 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { 1237 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
1216 HBasicBlock* b = graph()->CreateBasicBlock(); 1238 HBasicBlock* b = graph()->CreateBasicBlock();
1217 b->SetInitialEnvironment(env); 1239 b->SetInitialEnvironment(env);
1218 return b; 1240 return b;
1219 } 1241 }
1220 1242
1221 1243
(...skipping 3181 matching lines...) Expand 10 before | Expand all | Expand 10 after
4403 Add<HReturn>(result); 4425 Add<HReturn>(result);
4404 } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { 4426 } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) {
4405 // Return from an inlined construct call. In a test context the return value 4427 // Return from an inlined construct call. In a test context the return value
4406 // will always evaluate to true, in a value context the return value needs 4428 // will always evaluate to true, in a value context the return value needs
4407 // to be a JSObject. 4429 // to be a JSObject.
4408 if (context->IsTest()) { 4430 if (context->IsTest()) {
4409 TestContext* test = TestContext::cast(context); 4431 TestContext* test = TestContext::cast(context);
4410 CHECK_ALIVE(VisitForEffect(stmt->expression())); 4432 CHECK_ALIVE(VisitForEffect(stmt->expression()));
4411 Goto(test->if_true(), state); 4433 Goto(test->if_true(), state);
4412 } else if (context->IsEffect()) { 4434 } else if (context->IsEffect()) {
4413 CHECK_ALIVE(VisitForEffect(stmt->expression())); 4435 CHECK_ALIVE(VisitForValue(stmt->expression()));
4436 Drop(1);
4414 Goto(function_return(), state); 4437 Goto(function_return(), state);
4415 } else { 4438 } else {
4416 ASSERT(context->IsValue()); 4439 ASSERT(context->IsValue());
4417 CHECK_ALIVE(VisitForValue(stmt->expression())); 4440 CHECK_ALIVE(VisitForValue(stmt->expression()));
4418 HValue* return_value = Pop(); 4441 HValue* return_value = Pop();
4419 HValue* receiver = environment()->arguments_environment()->Lookup(0); 4442 HValue* receiver = environment()->arguments_environment()->Lookup(0);
4420 HHasInstanceTypeAndBranch* typecheck = 4443 HHasInstanceTypeAndBranch* typecheck =
4421 New<HHasInstanceTypeAndBranch>(return_value, 4444 New<HHasInstanceTypeAndBranch>(return_value,
4422 FIRST_SPEC_OBJECT_TYPE, 4445 FIRST_SPEC_OBJECT_TYPE,
4423 LAST_SPEC_OBJECT_TYPE); 4446 LAST_SPEC_OBJECT_TYPE);
(...skipping 3142 matching lines...) Expand 10 before | Expand all | Expand 10 after
7566 HEnterInlined* entry = function_state()->entry(); 7589 HEnterInlined* entry = function_state()->entry();
7567 7590
7568 // Pop the return test context from the expression context stack. 7591 // Pop the return test context from the expression context stack.
7569 ASSERT(ast_context() == inlined_test_context()); 7592 ASSERT(ast_context() == inlined_test_context());
7570 ClearInlinedTestContext(); 7593 ClearInlinedTestContext();
7571 delete target_state; 7594 delete target_state;
7572 7595
7573 // Forward to the real test context. 7596 // Forward to the real test context.
7574 if (if_true->HasPredecessor()) { 7597 if (if_true->HasPredecessor()) {
7575 entry->RegisterReturnTarget(if_true, zone()); 7598 entry->RegisterReturnTarget(if_true, zone());
7576 if_true->SetJoinId(ast_id); 7599 if_true->SetJoinId(ast_id, -1);
7577 HBasicBlock* true_target = TestContext::cast(ast_context())->if_true(); 7600 HBasicBlock* true_target = TestContext::cast(ast_context())->if_true();
7578 Goto(if_true, true_target, function_state()); 7601 Goto(if_true, true_target, function_state());
7579 } 7602 }
7580 if (if_false->HasPredecessor()) { 7603 if (if_false->HasPredecessor()) {
7581 entry->RegisterReturnTarget(if_false, zone()); 7604 entry->RegisterReturnTarget(if_false, zone());
7582 if_false->SetJoinId(ast_id); 7605 if_false->SetJoinId(ast_id, -1);
7583 HBasicBlock* false_target = TestContext::cast(ast_context())->if_false(); 7606 HBasicBlock* false_target = TestContext::cast(ast_context())->if_false();
7584 Goto(if_false, false_target, function_state()); 7607 Goto(if_false, false_target, function_state());
7585 } 7608 }
7586 set_current_block(NULL); 7609 set_current_block(NULL);
7587 return true; 7610 return true;
7588 7611
7589 } else if (function_return()->HasPredecessor()) { 7612 } else if (function_return()->HasPredecessor()) {
7590 function_state()->entry()->RegisterReturnTarget(function_return(), zone()); 7613 function_state()->entry()->RegisterReturnTarget(function_return(), zone());
7591 function_return()->SetJoinId(ast_id); 7614 function_return()->SetJoinId(ast_id);
7592 set_current_block(function_return()); 7615 set_current_block(function_return());
(...skipping 3254 matching lines...) Expand 10 before | Expand all | Expand 10 after
10847 ASSERT(call->arguments()->length() == 3); 10870 ASSERT(call->arguments()->length() == 3);
10848 // We need to follow the evaluation order of full codegen. 10871 // We need to follow the evaluation order of full codegen.
10849 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 10872 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
10850 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 10873 CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
10851 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10874 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10852 HValue* string = Pop(); 10875 HValue* string = Pop();
10853 HValue* value = Pop(); 10876 HValue* value = Pop();
10854 HValue* index = Pop(); 10877 HValue* index = Pop();
10855 Add<HSeqStringSetChar>(String::ONE_BYTE_ENCODING, string, 10878 Add<HSeqStringSetChar>(String::ONE_BYTE_ENCODING, string,
10856 index, value); 10879 index, value);
10857 Add<HSimulate>(call->id(), FIXED_SIMULATE); 10880 if (ast_context()->IsEffect()) {
10881 Add<HSimulate>(call->id(), FIXED_SIMULATE);
10882 } else {
10883 Push(graph()->GetConstantUndefined());
10884 Add<HSimulate>(call->id(), FIXED_SIMULATE);
10885 Pop();
10886 }
10858 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 10887 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
10859 } 10888 }
10860 10889
10861 10890
10862 void HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar( 10891 void HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar(
10863 CallRuntime* call) { 10892 CallRuntime* call) {
10864 ASSERT(call->arguments()->length() == 3); 10893 ASSERT(call->arguments()->length() == 3);
10865 // We need to follow the evaluation order of full codegen. 10894 // We need to follow the evaluation order of full codegen.
10866 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 10895 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
10867 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 10896 CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
10868 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10897 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10869 HValue* string = Pop(); 10898 HValue* string = Pop();
10870 HValue* value = Pop(); 10899 HValue* value = Pop();
10871 HValue* index = Pop(); 10900 HValue* index = Pop();
10872 Add<HSeqStringSetChar>(String::TWO_BYTE_ENCODING, string, 10901 Add<HSeqStringSetChar>(String::TWO_BYTE_ENCODING, string,
10873 index, value); 10902 index, value);
10874 Add<HSimulate>(call->id(), FIXED_SIMULATE); 10903 if (ast_context()->IsEffect()) {
10904 Add<HSimulate>(call->id(), FIXED_SIMULATE);
10905 } else {
10906 Push(graph()->GetConstantUndefined());
10907 Add<HSimulate>(call->id(), FIXED_SIMULATE);
10908 Pop();
10909 }
10875 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 10910 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
10876 } 10911 }
10877 10912
10878 10913
10879 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { 10914 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) {
10880 ASSERT(call->arguments()->length() == 2); 10915 ASSERT(call->arguments()->length() == 2);
10881 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10916 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10882 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 10917 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
10883 HValue* value = Pop(); 10918 HValue* value = Pop();
10884 HValue* object = Pop(); 10919 HValue* object = Pop();
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
11467 11502
11468 11503
11469 void HEnvironment::PrintToStd() { 11504 void HEnvironment::PrintToStd() {
11470 HeapStringAllocator string_allocator; 11505 HeapStringAllocator string_allocator;
11471 StringStream trace(&string_allocator); 11506 StringStream trace(&string_allocator);
11472 PrintTo(&trace); 11507 PrintTo(&trace);
11473 PrintF("%s", trace.ToCString().get()); 11508 PrintF("%s", trace.ToCString().get());
11474 } 11509 }
11475 11510
11476 11511
11512 void HEnvironment::VerifyStackHeight(
11513 BailoutId ast_id,
11514 int hydrogen_id,
11515 int stack_height_offset) {
11516 #if defined(COMPARE_OPT_STACK_HEIGHT)
11517 if (!ast_id.IsNone() && ast_id != BailoutId::StubEntry()) {
11518 int hydrogen_height = length() - specials_count() - parameter_count();
11519 int expected_stack_height =
11520 closure()->shared()->GetExpectedStackHeight(ast_id) +
11521 stack_height_offset;
11522
11523 if (expected_stack_height != hydrogen_height) {
11524 V8_Fatal(__FILE__, __LINE__,
11525 "Stack height mismatch.\n"
11526 "Hydrogen height = %4i, "
11527 "unoptimized height = %4i, AST id = %i\n",
11528 hydrogen_height, expected_stack_height, ast_id.ToInt());
11529 }
11530 }
11531 #endif
11532 }
11533
11534
11477 void HTracer::TraceCompilation(CompilationInfo* info) { 11535 void HTracer::TraceCompilation(CompilationInfo* info) {
11478 Tag tag(this, "compilation"); 11536 Tag tag(this, "compilation");
11479 if (info->IsOptimizing()) { 11537 if (info->IsOptimizing()) {
11480 Handle<String> name = info->function()->debug_name(); 11538 Handle<String> name = info->function()->debug_name();
11481 PrintStringProperty("name", name->ToCString().get()); 11539 PrintStringProperty("name", name->ToCString().get());
11482 PrintIndent(); 11540 PrintIndent();
11483 trace_.Add("method \"%s:%d\"\n", 11541 trace_.Add("method \"%s:%d\"\n",
11484 name->ToCString().get(), 11542 name->ToCString().get(),
11485 info->optimization_id()); 11543 info->optimization_id());
11486 } else { 11544 } else {
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
11805 if (ShouldProduceTraceOutput()) { 11863 if (ShouldProduceTraceOutput()) {
11806 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11864 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11807 } 11865 }
11808 11866
11809 #ifdef DEBUG 11867 #ifdef DEBUG
11810 graph_->Verify(false); // No full verify. 11868 graph_->Verify(false); // No full verify.
11811 #endif 11869 #endif
11812 } 11870 }
11813 11871
11814 } } // namespace v8::internal 11872 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698