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

Side by Side Diff: src/hydrogen.cc

Issue 430503007: Rename ASSERT* to DCHECK*. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE and fixes Created 6 years, 4 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-bce.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 "src/hydrogen.h" 5 #include "src/hydrogen.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 return graph_->isolate(); 92 return graph_->isolate();
93 } 93 }
94 94
95 95
96 void HBasicBlock::MarkUnreachable() { 96 void HBasicBlock::MarkUnreachable() {
97 is_reachable_ = false; 97 is_reachable_ = false;
98 } 98 }
99 99
100 100
101 void HBasicBlock::AttachLoopInformation() { 101 void HBasicBlock::AttachLoopInformation() {
102 ASSERT(!IsLoopHeader()); 102 DCHECK(!IsLoopHeader());
103 loop_information_ = new(zone()) HLoopInformation(this, zone()); 103 loop_information_ = new(zone()) HLoopInformation(this, zone());
104 } 104 }
105 105
106 106
107 void HBasicBlock::DetachLoopInformation() { 107 void HBasicBlock::DetachLoopInformation() {
108 ASSERT(IsLoopHeader()); 108 DCHECK(IsLoopHeader());
109 loop_information_ = NULL; 109 loop_information_ = NULL;
110 } 110 }
111 111
112 112
113 void HBasicBlock::AddPhi(HPhi* phi) { 113 void HBasicBlock::AddPhi(HPhi* phi) {
114 ASSERT(!IsStartBlock()); 114 DCHECK(!IsStartBlock());
115 phis_.Add(phi, zone()); 115 phis_.Add(phi, zone());
116 phi->SetBlock(this); 116 phi->SetBlock(this);
117 } 117 }
118 118
119 119
120 void HBasicBlock::RemovePhi(HPhi* phi) { 120 void HBasicBlock::RemovePhi(HPhi* phi) {
121 ASSERT(phi->block() == this); 121 DCHECK(phi->block() == this);
122 ASSERT(phis_.Contains(phi)); 122 DCHECK(phis_.Contains(phi));
123 phi->Kill(); 123 phi->Kill();
124 phis_.RemoveElement(phi); 124 phis_.RemoveElement(phi);
125 phi->SetBlock(NULL); 125 phi->SetBlock(NULL);
126 } 126 }
127 127
128 128
129 void HBasicBlock::AddInstruction(HInstruction* instr, 129 void HBasicBlock::AddInstruction(HInstruction* instr,
130 HSourcePosition position) { 130 HSourcePosition position) {
131 ASSERT(!IsStartBlock() || !IsFinished()); 131 DCHECK(!IsStartBlock() || !IsFinished());
132 ASSERT(!instr->IsLinked()); 132 DCHECK(!instr->IsLinked());
133 ASSERT(!IsFinished()); 133 DCHECK(!IsFinished());
134 134
135 if (!position.IsUnknown()) { 135 if (!position.IsUnknown()) {
136 instr->set_position(position); 136 instr->set_position(position);
137 } 137 }
138 if (first_ == NULL) { 138 if (first_ == NULL) {
139 ASSERT(last_environment() != NULL); 139 DCHECK(last_environment() != NULL);
140 ASSERT(!last_environment()->ast_id().IsNone()); 140 DCHECK(!last_environment()->ast_id().IsNone());
141 HBlockEntry* entry = new(zone()) HBlockEntry(); 141 HBlockEntry* entry = new(zone()) HBlockEntry();
142 entry->InitializeAsFirst(this); 142 entry->InitializeAsFirst(this);
143 if (!position.IsUnknown()) { 143 if (!position.IsUnknown()) {
144 entry->set_position(position); 144 entry->set_position(position);
145 } else { 145 } else {
146 ASSERT(!FLAG_hydrogen_track_positions || 146 DCHECK(!FLAG_hydrogen_track_positions ||
147 !graph()->info()->IsOptimizing()); 147 !graph()->info()->IsOptimizing());
148 } 148 }
149 first_ = last_ = entry; 149 first_ = last_ = entry;
150 } 150 }
151 instr->InsertAfter(last_); 151 instr->InsertAfter(last_);
152 } 152 }
153 153
154 154
155 HPhi* HBasicBlock::AddNewPhi(int merged_index) { 155 HPhi* HBasicBlock::AddNewPhi(int merged_index) {
156 if (graph()->IsInsideNoSideEffectsScope()) { 156 if (graph()->IsInsideNoSideEffectsScope()) {
157 merged_index = HPhi::kInvalidMergedIndex; 157 merged_index = HPhi::kInvalidMergedIndex;
158 } 158 }
159 HPhi* phi = new(zone()) HPhi(merged_index, zone()); 159 HPhi* phi = new(zone()) HPhi(merged_index, zone());
160 AddPhi(phi); 160 AddPhi(phi);
161 return phi; 161 return phi;
162 } 162 }
163 163
164 164
165 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id, 165 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id,
166 RemovableSimulate removable) { 166 RemovableSimulate removable) {
167 ASSERT(HasEnvironment()); 167 DCHECK(HasEnvironment());
168 HEnvironment* environment = last_environment(); 168 HEnvironment* environment = last_environment();
169 ASSERT(ast_id.IsNone() || 169 DCHECK(ast_id.IsNone() ||
170 ast_id == BailoutId::StubEntry() || 170 ast_id == BailoutId::StubEntry() ||
171 environment->closure()->shared()->VerifyBailoutId(ast_id)); 171 environment->closure()->shared()->VerifyBailoutId(ast_id));
172 172
173 int push_count = environment->push_count(); 173 int push_count = environment->push_count();
174 int pop_count = environment->pop_count(); 174 int pop_count = environment->pop_count();
175 175
176 HSimulate* instr = 176 HSimulate* instr =
177 new(zone()) HSimulate(ast_id, pop_count, zone(), removable); 177 new(zone()) HSimulate(ast_id, pop_count, zone(), removable);
178 #ifdef DEBUG 178 #ifdef DEBUG
179 instr->set_closure(environment->closure()); 179 instr->set_closure(environment->closure());
(...skipping 10 matching lines...) Expand all
190 it.Advance()) { 190 it.Advance()) {
191 int index = it.Current(); 191 int index = it.Current();
192 instr->AddAssignedValue(index, environment->Lookup(index)); 192 instr->AddAssignedValue(index, environment->Lookup(index));
193 } 193 }
194 environment->ClearHistory(); 194 environment->ClearHistory();
195 return instr; 195 return instr;
196 } 196 }
197 197
198 198
199 void HBasicBlock::Finish(HControlInstruction* end, HSourcePosition position) { 199 void HBasicBlock::Finish(HControlInstruction* end, HSourcePosition position) {
200 ASSERT(!IsFinished()); 200 DCHECK(!IsFinished());
201 AddInstruction(end, position); 201 AddInstruction(end, position);
202 end_ = end; 202 end_ = end;
203 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { 203 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) {
204 it.Current()->RegisterPredecessor(this); 204 it.Current()->RegisterPredecessor(this);
205 } 205 }
206 } 206 }
207 207
208 208
209 void HBasicBlock::Goto(HBasicBlock* block, 209 void HBasicBlock::Goto(HBasicBlock* block,
210 HSourcePosition position, 210 HSourcePosition position,
(...skipping 16 matching lines...) Expand all
227 Finish(instr, position); 227 Finish(instr, position);
228 } 228 }
229 229
230 230
231 void HBasicBlock::AddLeaveInlined(HValue* return_value, 231 void HBasicBlock::AddLeaveInlined(HValue* return_value,
232 FunctionState* state, 232 FunctionState* state,
233 HSourcePosition position) { 233 HSourcePosition position) {
234 HBasicBlock* target = state->function_return(); 234 HBasicBlock* target = state->function_return();
235 bool drop_extra = state->inlining_kind() == NORMAL_RETURN; 235 bool drop_extra = state->inlining_kind() == NORMAL_RETURN;
236 236
237 ASSERT(target->IsInlineReturnTarget()); 237 DCHECK(target->IsInlineReturnTarget());
238 ASSERT(return_value != NULL); 238 DCHECK(return_value != NULL);
239 HEnvironment* env = last_environment(); 239 HEnvironment* env = last_environment();
240 int argument_count = env->arguments_environment()->parameter_count(); 240 int argument_count = env->arguments_environment()->parameter_count();
241 AddInstruction(new(zone()) HLeaveInlined(state->entry(), argument_count), 241 AddInstruction(new(zone()) HLeaveInlined(state->entry(), argument_count),
242 position); 242 position);
243 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); 243 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra));
244 last_environment()->Push(return_value); 244 last_environment()->Push(return_value);
245 AddNewSimulate(BailoutId::None(), position); 245 AddNewSimulate(BailoutId::None(), position);
246 HGoto* instr = new(zone()) HGoto(target); 246 HGoto* instr = new(zone()) HGoto(target);
247 Finish(instr, position); 247 Finish(instr, position);
248 } 248 }
249 249
250 250
251 void HBasicBlock::SetInitialEnvironment(HEnvironment* env) { 251 void HBasicBlock::SetInitialEnvironment(HEnvironment* env) {
252 ASSERT(!HasEnvironment()); 252 DCHECK(!HasEnvironment());
253 ASSERT(first() == NULL); 253 DCHECK(first() == NULL);
254 UpdateEnvironment(env); 254 UpdateEnvironment(env);
255 } 255 }
256 256
257 257
258 void HBasicBlock::UpdateEnvironment(HEnvironment* env) { 258 void HBasicBlock::UpdateEnvironment(HEnvironment* env) {
259 last_environment_ = env; 259 last_environment_ = env;
260 graph()->update_maximum_environment_size(env->first_expression_index()); 260 graph()->update_maximum_environment_size(env->first_expression_index());
261 } 261 }
262 262
263 263
264 void HBasicBlock::SetJoinId(BailoutId ast_id) { 264 void HBasicBlock::SetJoinId(BailoutId ast_id) {
265 int length = predecessors_.length(); 265 int length = predecessors_.length();
266 ASSERT(length > 0); 266 DCHECK(length > 0);
267 for (int i = 0; i < length; i++) { 267 for (int i = 0; i < length; i++) {
268 HBasicBlock* predecessor = predecessors_[i]; 268 HBasicBlock* predecessor = predecessors_[i];
269 ASSERT(predecessor->end()->IsGoto()); 269 DCHECK(predecessor->end()->IsGoto());
270 HSimulate* simulate = HSimulate::cast(predecessor->end()->previous()); 270 HSimulate* simulate = HSimulate::cast(predecessor->end()->previous());
271 ASSERT(i != 0 || 271 DCHECK(i != 0 ||
272 (predecessor->last_environment()->closure().is_null() || 272 (predecessor->last_environment()->closure().is_null() ||
273 predecessor->last_environment()->closure()->shared() 273 predecessor->last_environment()->closure()->shared()
274 ->VerifyBailoutId(ast_id))); 274 ->VerifyBailoutId(ast_id)));
275 simulate->set_ast_id(ast_id); 275 simulate->set_ast_id(ast_id);
276 predecessor->last_environment()->set_ast_id(ast_id); 276 predecessor->last_environment()->set_ast_id(ast_id);
277 } 277 }
278 } 278 }
279 279
280 280
281 bool HBasicBlock::Dominates(HBasicBlock* other) const { 281 bool HBasicBlock::Dominates(HBasicBlock* other) const {
(...skipping 17 matching lines...) Expand all
299 int result = (current->IsLoopHeader()) ? 1 : 0; 299 int result = (current->IsLoopHeader()) ? 1 : 0;
300 while (current->parent_loop_header() != NULL) { 300 while (current->parent_loop_header() != NULL) {
301 current = current->parent_loop_header(); 301 current = current->parent_loop_header();
302 result++; 302 result++;
303 } 303 }
304 return result; 304 return result;
305 } 305 }
306 306
307 307
308 void HBasicBlock::PostProcessLoopHeader(IterationStatement* stmt) { 308 void HBasicBlock::PostProcessLoopHeader(IterationStatement* stmt) {
309 ASSERT(IsLoopHeader()); 309 DCHECK(IsLoopHeader());
310 310
311 SetJoinId(stmt->EntryId()); 311 SetJoinId(stmt->EntryId());
312 if (predecessors()->length() == 1) { 312 if (predecessors()->length() == 1) {
313 // This is a degenerated loop. 313 // This is a degenerated loop.
314 DetachLoopInformation(); 314 DetachLoopInformation();
315 return; 315 return;
316 } 316 }
317 317
318 // Only the first entry into the loop is from outside the loop. All other 318 // Only the first entry into the loop is from outside the loop. All other
319 // entries must be back edges. 319 // entries must be back edges.
320 for (int i = 1; i < predecessors()->length(); ++i) { 320 for (int i = 1; i < predecessors()->length(); ++i) {
321 loop_information()->RegisterBackEdge(predecessors()->at(i)); 321 loop_information()->RegisterBackEdge(predecessors()->at(i));
322 } 322 }
323 } 323 }
324 324
325 325
326 void HBasicBlock::MarkSuccEdgeUnreachable(int succ) { 326 void HBasicBlock::MarkSuccEdgeUnreachable(int succ) {
327 ASSERT(IsFinished()); 327 DCHECK(IsFinished());
328 HBasicBlock* succ_block = end()->SuccessorAt(succ); 328 HBasicBlock* succ_block = end()->SuccessorAt(succ);
329 329
330 ASSERT(succ_block->predecessors()->length() == 1); 330 DCHECK(succ_block->predecessors()->length() == 1);
331 succ_block->MarkUnreachable(); 331 succ_block->MarkUnreachable();
332 } 332 }
333 333
334 334
335 void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { 335 void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) {
336 if (HasPredecessor()) { 336 if (HasPredecessor()) {
337 // Only loop header blocks can have a predecessor added after 337 // Only loop header blocks can have a predecessor added after
338 // instructions have been added to the block (they have phis for all 338 // instructions have been added to the block (they have phis for all
339 // values in the environment, these phis may be eliminated later). 339 // values in the environment, these phis may be eliminated later).
340 ASSERT(IsLoopHeader() || first_ == NULL); 340 DCHECK(IsLoopHeader() || first_ == NULL);
341 HEnvironment* incoming_env = pred->last_environment(); 341 HEnvironment* incoming_env = pred->last_environment();
342 if (IsLoopHeader()) { 342 if (IsLoopHeader()) {
343 ASSERT(phis()->length() == incoming_env->length()); 343 DCHECK(phis()->length() == incoming_env->length());
344 for (int i = 0; i < phis_.length(); ++i) { 344 for (int i = 0; i < phis_.length(); ++i) {
345 phis_[i]->AddInput(incoming_env->values()->at(i)); 345 phis_[i]->AddInput(incoming_env->values()->at(i));
346 } 346 }
347 } else { 347 } else {
348 last_environment()->AddIncomingEdge(this, pred->last_environment()); 348 last_environment()->AddIncomingEdge(this, pred->last_environment());
349 } 349 }
350 } else if (!HasEnvironment() && !IsFinished()) { 350 } else if (!HasEnvironment() && !IsFinished()) {
351 ASSERT(!IsLoopHeader()); 351 DCHECK(!IsLoopHeader());
352 SetInitialEnvironment(pred->last_environment()->Copy()); 352 SetInitialEnvironment(pred->last_environment()->Copy());
353 } 353 }
354 354
355 predecessors_.Add(pred, zone()); 355 predecessors_.Add(pred, zone());
356 } 356 }
357 357
358 358
359 void HBasicBlock::AddDominatedBlock(HBasicBlock* block) { 359 void HBasicBlock::AddDominatedBlock(HBasicBlock* block) {
360 ASSERT(!dominated_blocks_.Contains(block)); 360 DCHECK(!dominated_blocks_.Contains(block));
361 // Keep the list of dominated blocks sorted such that if there is two 361 // Keep the list of dominated blocks sorted such that if there is two
362 // succeeding block in this list, the predecessor is before the successor. 362 // succeeding block in this list, the predecessor is before the successor.
363 int index = 0; 363 int index = 0;
364 while (index < dominated_blocks_.length() && 364 while (index < dominated_blocks_.length() &&
365 dominated_blocks_[index]->block_id() < block->block_id()) { 365 dominated_blocks_[index]->block_id() < block->block_id()) {
366 ++index; 366 ++index;
367 } 367 }
368 dominated_blocks_.InsertAt(index, block, zone()); 368 dominated_blocks_.InsertAt(index, block, zone());
369 } 369 }
370 370
371 371
372 void HBasicBlock::AssignCommonDominator(HBasicBlock* other) { 372 void HBasicBlock::AssignCommonDominator(HBasicBlock* other) {
373 if (dominator_ == NULL) { 373 if (dominator_ == NULL) {
374 dominator_ = other; 374 dominator_ = other;
375 other->AddDominatedBlock(this); 375 other->AddDominatedBlock(this);
376 } else if (other->dominator() != NULL) { 376 } else if (other->dominator() != NULL) {
377 HBasicBlock* first = dominator_; 377 HBasicBlock* first = dominator_;
378 HBasicBlock* second = other; 378 HBasicBlock* second = other;
379 379
380 while (first != second) { 380 while (first != second) {
381 if (first->block_id() > second->block_id()) { 381 if (first->block_id() > second->block_id()) {
382 first = first->dominator(); 382 first = first->dominator();
383 } else { 383 } else {
384 second = second->dominator(); 384 second = second->dominator();
385 } 385 }
386 ASSERT(first != NULL && second != NULL); 386 DCHECK(first != NULL && second != NULL);
387 } 387 }
388 388
389 if (dominator_ != first) { 389 if (dominator_ != first) {
390 ASSERT(dominator_->dominated_blocks_.Contains(this)); 390 DCHECK(dominator_->dominated_blocks_.Contains(this));
391 dominator_->dominated_blocks_.RemoveElement(this); 391 dominator_->dominated_blocks_.RemoveElement(this);
392 dominator_ = first; 392 dominator_ = first;
393 first->AddDominatedBlock(this); 393 first->AddDominatedBlock(this);
394 } 394 }
395 } 395 }
396 } 396 }
397 397
398 398
399 void HBasicBlock::AssignLoopSuccessorDominators() { 399 void HBasicBlock::AssignLoopSuccessorDominators() {
400 // Mark blocks that dominate all subsequent reachable blocks inside their 400 // Mark blocks that dominate all subsequent reachable blocks inside their
(...skipping 21 matching lines...) Expand all
422 } 422 }
423 423
424 // If more successors than predecessors have been seen in the loop up to 424 // If more successors than predecessors have been seen in the loop up to
425 // now, it's not possible to guarantee that the current block dominates 425 // now, it's not possible to guarantee that the current block dominates
426 // all of the blocks with higher IDs. In this case, assume conservatively 426 // all of the blocks with higher IDs. In this case, assume conservatively
427 // that those paths through loop that don't go through the current block 427 // that those paths through loop that don't go through the current block
428 // contain all of the loop's dependencies. Also be careful to record 428 // contain all of the loop's dependencies. Also be careful to record
429 // dominator information about the current loop that's being processed, 429 // dominator information about the current loop that's being processed,
430 // and not nested loops, which will be processed when 430 // and not nested loops, which will be processed when
431 // AssignLoopSuccessorDominators gets called on their header. 431 // AssignLoopSuccessorDominators gets called on their header.
432 ASSERT(outstanding_successors >= 0); 432 DCHECK(outstanding_successors >= 0);
433 HBasicBlock* parent_loop_header = dominator_candidate->parent_loop_header(); 433 HBasicBlock* parent_loop_header = dominator_candidate->parent_loop_header();
434 if (outstanding_successors == 0 && 434 if (outstanding_successors == 0 &&
435 (parent_loop_header == this && !dominator_candidate->IsLoopHeader())) { 435 (parent_loop_header == this && !dominator_candidate->IsLoopHeader())) {
436 dominator_candidate->MarkAsLoopSuccessorDominator(); 436 dominator_candidate->MarkAsLoopSuccessorDominator();
437 } 437 }
438 HControlInstruction* end = dominator_candidate->end(); 438 HControlInstruction* end = dominator_candidate->end();
439 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { 439 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) {
440 HBasicBlock* successor = it.Current(); 440 HBasicBlock* successor = it.Current();
441 // Only count successors that remain inside the loop and don't loop back 441 // Only count successors that remain inside the loop and don't loop back
442 // to a loop header. 442 // to a loop header.
443 if (successor->block_id() > dominator_candidate->block_id() && 443 if (successor->block_id() > dominator_candidate->block_id() &&
444 successor->block_id() <= last->block_id()) { 444 successor->block_id() <= last->block_id()) {
445 // Backwards edges must land on loop headers. 445 // Backwards edges must land on loop headers.
446 ASSERT(successor->block_id() > dominator_candidate->block_id() || 446 DCHECK(successor->block_id() > dominator_candidate->block_id() ||
447 successor->IsLoopHeader()); 447 successor->IsLoopHeader());
448 outstanding_successors++; 448 outstanding_successors++;
449 } 449 }
450 } 450 }
451 } 451 }
452 } 452 }
453 453
454 454
455 int HBasicBlock::PredecessorIndexOf(HBasicBlock* predecessor) const { 455 int HBasicBlock::PredecessorIndexOf(HBasicBlock* predecessor) const {
456 for (int i = 0; i < predecessors_.length(); ++i) { 456 for (int i = 0; i < predecessors_.length(); ++i) {
457 if (predecessors_[i] == predecessor) return i; 457 if (predecessors_[i] == predecessor) return i;
458 } 458 }
459 UNREACHABLE(); 459 UNREACHABLE();
460 return -1; 460 return -1;
461 } 461 }
462 462
463 463
464 #ifdef DEBUG 464 #ifdef DEBUG
465 void HBasicBlock::Verify() { 465 void HBasicBlock::Verify() {
466 // Check that every block is finished. 466 // Check that every block is finished.
467 ASSERT(IsFinished()); 467 DCHECK(IsFinished());
468 ASSERT(block_id() >= 0); 468 DCHECK(block_id() >= 0);
469 469
470 // Check that the incoming edges are in edge split form. 470 // Check that the incoming edges are in edge split form.
471 if (predecessors_.length() > 1) { 471 if (predecessors_.length() > 1) {
472 for (int i = 0; i < predecessors_.length(); ++i) { 472 for (int i = 0; i < predecessors_.length(); ++i) {
473 ASSERT(predecessors_[i]->end()->SecondSuccessor() == NULL); 473 DCHECK(predecessors_[i]->end()->SecondSuccessor() == NULL);
474 } 474 }
475 } 475 }
476 } 476 }
477 #endif 477 #endif
478 478
479 479
480 void HLoopInformation::RegisterBackEdge(HBasicBlock* block) { 480 void HLoopInformation::RegisterBackEdge(HBasicBlock* block) {
481 this->back_edges_.Add(block, block->zone()); 481 this->back_edges_.Add(block, block->zone());
482 AddBlock(block); 482 AddBlock(block);
483 } 483 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 AllowHandleDereference allow_deref; 566 AllowHandleDereference allow_deref;
567 AllowDeferredHandleDereference allow_deferred_deref; 567 AllowDeferredHandleDereference allow_deferred_deref;
568 for (int i = 0; i < blocks_.length(); i++) { 568 for (int i = 0; i < blocks_.length(); i++) {
569 HBasicBlock* block = blocks_.at(i); 569 HBasicBlock* block = blocks_.at(i);
570 570
571 block->Verify(); 571 block->Verify();
572 572
573 // Check that every block contains at least one node and that only the last 573 // Check that every block contains at least one node and that only the last
574 // node is a control instruction. 574 // node is a control instruction.
575 HInstruction* current = block->first(); 575 HInstruction* current = block->first();
576 ASSERT(current != NULL && current->IsBlockEntry()); 576 DCHECK(current != NULL && current->IsBlockEntry());
577 while (current != NULL) { 577 while (current != NULL) {
578 ASSERT((current->next() == NULL) == current->IsControlInstruction()); 578 DCHECK((current->next() == NULL) == current->IsControlInstruction());
579 ASSERT(current->block() == block); 579 DCHECK(current->block() == block);
580 current->Verify(); 580 current->Verify();
581 current = current->next(); 581 current = current->next();
582 } 582 }
583 583
584 // Check that successors are correctly set. 584 // Check that successors are correctly set.
585 HBasicBlock* first = block->end()->FirstSuccessor(); 585 HBasicBlock* first = block->end()->FirstSuccessor();
586 HBasicBlock* second = block->end()->SecondSuccessor(); 586 HBasicBlock* second = block->end()->SecondSuccessor();
587 ASSERT(second == NULL || first != NULL); 587 DCHECK(second == NULL || first != NULL);
588 588
589 // Check that the predecessor array is correct. 589 // Check that the predecessor array is correct.
590 if (first != NULL) { 590 if (first != NULL) {
591 ASSERT(first->predecessors()->Contains(block)); 591 DCHECK(first->predecessors()->Contains(block));
592 if (second != NULL) { 592 if (second != NULL) {
593 ASSERT(second->predecessors()->Contains(block)); 593 DCHECK(second->predecessors()->Contains(block));
594 } 594 }
595 } 595 }
596 596
597 // Check that phis have correct arguments. 597 // Check that phis have correct arguments.
598 for (int j = 0; j < block->phis()->length(); j++) { 598 for (int j = 0; j < block->phis()->length(); j++) {
599 HPhi* phi = block->phis()->at(j); 599 HPhi* phi = block->phis()->at(j);
600 phi->Verify(); 600 phi->Verify();
601 } 601 }
602 602
603 // Check that all join blocks have predecessors that end with an 603 // Check that all join blocks have predecessors that end with an
604 // unconditional goto and agree on their environment node id. 604 // unconditional goto and agree on their environment node id.
605 if (block->predecessors()->length() >= 2) { 605 if (block->predecessors()->length() >= 2) {
606 BailoutId id = 606 BailoutId id =
607 block->predecessors()->first()->last_environment()->ast_id(); 607 block->predecessors()->first()->last_environment()->ast_id();
608 for (int k = 0; k < block->predecessors()->length(); k++) { 608 for (int k = 0; k < block->predecessors()->length(); k++) {
609 HBasicBlock* predecessor = block->predecessors()->at(k); 609 HBasicBlock* predecessor = block->predecessors()->at(k);
610 ASSERT(predecessor->end()->IsGoto() || 610 DCHECK(predecessor->end()->IsGoto() ||
611 predecessor->end()->IsDeoptimize()); 611 predecessor->end()->IsDeoptimize());
612 ASSERT(predecessor->last_environment()->ast_id() == id); 612 DCHECK(predecessor->last_environment()->ast_id() == id);
613 } 613 }
614 } 614 }
615 } 615 }
616 616
617 // Check special property of first block to have no predecessors. 617 // Check special property of first block to have no predecessors.
618 ASSERT(blocks_.at(0)->predecessors()->is_empty()); 618 DCHECK(blocks_.at(0)->predecessors()->is_empty());
619 619
620 if (do_full_verify) { 620 if (do_full_verify) {
621 // Check that the graph is fully connected. 621 // Check that the graph is fully connected.
622 ReachabilityAnalyzer analyzer(entry_block_, blocks_.length(), NULL); 622 ReachabilityAnalyzer analyzer(entry_block_, blocks_.length(), NULL);
623 ASSERT(analyzer.visited_count() == blocks_.length()); 623 DCHECK(analyzer.visited_count() == blocks_.length());
624 624
625 // Check that entry block dominator is NULL. 625 // Check that entry block dominator is NULL.
626 ASSERT(entry_block_->dominator() == NULL); 626 DCHECK(entry_block_->dominator() == NULL);
627 627
628 // Check dominators. 628 // Check dominators.
629 for (int i = 0; i < blocks_.length(); ++i) { 629 for (int i = 0; i < blocks_.length(); ++i) {
630 HBasicBlock* block = blocks_.at(i); 630 HBasicBlock* block = blocks_.at(i);
631 if (block->dominator() == NULL) { 631 if (block->dominator() == NULL) {
632 // Only start block may have no dominator assigned to. 632 // Only start block may have no dominator assigned to.
633 ASSERT(i == 0); 633 DCHECK(i == 0);
634 } else { 634 } else {
635 // Assert that block is unreachable if dominator must not be visited. 635 // Assert that block is unreachable if dominator must not be visited.
636 ReachabilityAnalyzer dominator_analyzer(entry_block_, 636 ReachabilityAnalyzer dominator_analyzer(entry_block_,
637 blocks_.length(), 637 blocks_.length(),
638 block->dominator()); 638 block->dominator());
639 ASSERT(!dominator_analyzer.reachable()->Contains(block->block_id())); 639 DCHECK(!dominator_analyzer.reachable()->Contains(block->block_id()));
640 } 640 }
641 } 641 }
642 } 642 }
643 } 643 }
644 644
645 #endif 645 #endif
646 646
647 647
648 HConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer, 648 HConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer,
649 int32_t value) { 649 int32_t value) {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 void HGraphBuilder::IfBuilder::Initialize(HGraphBuilder* builder) { 785 void HGraphBuilder::IfBuilder::Initialize(HGraphBuilder* builder) {
786 InitializeDontCreateBlocks(builder); 786 InitializeDontCreateBlocks(builder);
787 HEnvironment* env = builder->environment(); 787 HEnvironment* env = builder->environment();
788 first_true_block_ = builder->CreateBasicBlock(env->Copy()); 788 first_true_block_ = builder->CreateBasicBlock(env->Copy());
789 first_false_block_ = builder->CreateBasicBlock(env->Copy()); 789 first_false_block_ = builder->CreateBasicBlock(env->Copy());
790 } 790 }
791 791
792 792
793 HControlInstruction* HGraphBuilder::IfBuilder::AddCompare( 793 HControlInstruction* HGraphBuilder::IfBuilder::AddCompare(
794 HControlInstruction* compare) { 794 HControlInstruction* compare) {
795 ASSERT(did_then_ == did_else_); 795 DCHECK(did_then_ == did_else_);
796 if (did_else_) { 796 if (did_else_) {
797 // Handle if-then-elseif 797 // Handle if-then-elseif
798 did_else_if_ = true; 798 did_else_if_ = true;
799 did_else_ = false; 799 did_else_ = false;
800 did_then_ = false; 800 did_then_ = false;
801 did_and_ = false; 801 did_and_ = false;
802 did_or_ = false; 802 did_or_ = false;
803 pending_merge_block_ = false; 803 pending_merge_block_ = false;
804 split_edge_merge_block_ = NULL; 804 split_edge_merge_block_ = NULL;
805 HEnvironment* env = builder()->environment(); 805 HEnvironment* env = builder()->environment();
(...skipping 15 matching lines...) Expand all
821 compare->SetSuccessorAt(0, first_true_block_); 821 compare->SetSuccessorAt(0, first_true_block_);
822 compare->SetSuccessorAt(1, first_false_block_); 822 compare->SetSuccessorAt(1, first_false_block_);
823 } 823 }
824 builder()->FinishCurrentBlock(compare); 824 builder()->FinishCurrentBlock(compare);
825 needs_compare_ = false; 825 needs_compare_ = false;
826 return compare; 826 return compare;
827 } 827 }
828 828
829 829
830 void HGraphBuilder::IfBuilder::Or() { 830 void HGraphBuilder::IfBuilder::Or() {
831 ASSERT(!needs_compare_); 831 DCHECK(!needs_compare_);
832 ASSERT(!did_and_); 832 DCHECK(!did_and_);
833 did_or_ = true; 833 did_or_ = true;
834 HEnvironment* env = first_false_block_->last_environment(); 834 HEnvironment* env = first_false_block_->last_environment();
835 if (split_edge_merge_block_ == NULL) { 835 if (split_edge_merge_block_ == NULL) {
836 split_edge_merge_block_ = builder()->CreateBasicBlock(env->Copy()); 836 split_edge_merge_block_ = builder()->CreateBasicBlock(env->Copy());
837 builder()->GotoNoSimulate(first_true_block_, split_edge_merge_block_); 837 builder()->GotoNoSimulate(first_true_block_, split_edge_merge_block_);
838 first_true_block_ = split_edge_merge_block_; 838 first_true_block_ = split_edge_merge_block_;
839 } 839 }
840 builder()->set_current_block(first_false_block_); 840 builder()->set_current_block(first_false_block_);
841 first_false_block_ = builder()->CreateBasicBlock(env->Copy()); 841 first_false_block_ = builder()->CreateBasicBlock(env->Copy());
842 } 842 }
843 843
844 844
845 void HGraphBuilder::IfBuilder::And() { 845 void HGraphBuilder::IfBuilder::And() {
846 ASSERT(!needs_compare_); 846 DCHECK(!needs_compare_);
847 ASSERT(!did_or_); 847 DCHECK(!did_or_);
848 did_and_ = true; 848 did_and_ = true;
849 HEnvironment* env = first_false_block_->last_environment(); 849 HEnvironment* env = first_false_block_->last_environment();
850 if (split_edge_merge_block_ == NULL) { 850 if (split_edge_merge_block_ == NULL) {
851 split_edge_merge_block_ = builder()->CreateBasicBlock(env->Copy()); 851 split_edge_merge_block_ = builder()->CreateBasicBlock(env->Copy());
852 builder()->GotoNoSimulate(first_false_block_, split_edge_merge_block_); 852 builder()->GotoNoSimulate(first_false_block_, split_edge_merge_block_);
853 first_false_block_ = split_edge_merge_block_; 853 first_false_block_ = split_edge_merge_block_;
854 } 854 }
855 builder()->set_current_block(first_true_block_); 855 builder()->set_current_block(first_true_block_);
856 first_true_block_ = builder()->CreateBasicBlock(env->Copy()); 856 first_true_block_ = builder()->CreateBasicBlock(env->Copy());
857 } 857 }
858 858
859 859
860 void HGraphBuilder::IfBuilder::CaptureContinuation( 860 void HGraphBuilder::IfBuilder::CaptureContinuation(
861 HIfContinuation* continuation) { 861 HIfContinuation* continuation) {
862 ASSERT(!did_else_if_); 862 DCHECK(!did_else_if_);
863 ASSERT(!finished_); 863 DCHECK(!finished_);
864 ASSERT(!captured_); 864 DCHECK(!captured_);
865 865
866 HBasicBlock* true_block = NULL; 866 HBasicBlock* true_block = NULL;
867 HBasicBlock* false_block = NULL; 867 HBasicBlock* false_block = NULL;
868 Finish(&true_block, &false_block); 868 Finish(&true_block, &false_block);
869 ASSERT(true_block != NULL); 869 DCHECK(true_block != NULL);
870 ASSERT(false_block != NULL); 870 DCHECK(false_block != NULL);
871 continuation->Capture(true_block, false_block); 871 continuation->Capture(true_block, false_block);
872 captured_ = true; 872 captured_ = true;
873 builder()->set_current_block(NULL); 873 builder()->set_current_block(NULL);
874 End(); 874 End();
875 } 875 }
876 876
877 877
878 void HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) { 878 void HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) {
879 ASSERT(!did_else_if_); 879 DCHECK(!did_else_if_);
880 ASSERT(!finished_); 880 DCHECK(!finished_);
881 ASSERT(!captured_); 881 DCHECK(!captured_);
882 HBasicBlock* true_block = NULL; 882 HBasicBlock* true_block = NULL;
883 HBasicBlock* false_block = NULL; 883 HBasicBlock* false_block = NULL;
884 Finish(&true_block, &false_block); 884 Finish(&true_block, &false_block);
885 merge_at_join_blocks_ = NULL; 885 merge_at_join_blocks_ = NULL;
886 if (true_block != NULL && !true_block->IsFinished()) { 886 if (true_block != NULL && !true_block->IsFinished()) {
887 ASSERT(continuation->IsTrueReachable()); 887 DCHECK(continuation->IsTrueReachable());
888 builder()->GotoNoSimulate(true_block, continuation->true_branch()); 888 builder()->GotoNoSimulate(true_block, continuation->true_branch());
889 } 889 }
890 if (false_block != NULL && !false_block->IsFinished()) { 890 if (false_block != NULL && !false_block->IsFinished()) {
891 ASSERT(continuation->IsFalseReachable()); 891 DCHECK(continuation->IsFalseReachable());
892 builder()->GotoNoSimulate(false_block, continuation->false_branch()); 892 builder()->GotoNoSimulate(false_block, continuation->false_branch());
893 } 893 }
894 captured_ = true; 894 captured_ = true;
895 End(); 895 End();
896 } 896 }
897 897
898 898
899 void HGraphBuilder::IfBuilder::Then() { 899 void HGraphBuilder::IfBuilder::Then() {
900 ASSERT(!captured_); 900 DCHECK(!captured_);
901 ASSERT(!finished_); 901 DCHECK(!finished_);
902 did_then_ = true; 902 did_then_ = true;
903 if (needs_compare_) { 903 if (needs_compare_) {
904 // Handle if's without any expressions, they jump directly to the "else" 904 // Handle if's without any expressions, they jump directly to the "else"
905 // branch. However, we must pretend that the "then" branch is reachable, 905 // branch. However, we must pretend that the "then" branch is reachable,
906 // so that the graph builder visits it and sees any live range extending 906 // so that the graph builder visits it and sees any live range extending
907 // constructs within it. 907 // constructs within it.
908 HConstant* constant_false = builder()->graph()->GetConstantFalse(); 908 HConstant* constant_false = builder()->graph()->GetConstantFalse();
909 ToBooleanStub::Types boolean_type = ToBooleanStub::Types(); 909 ToBooleanStub::Types boolean_type = ToBooleanStub::Types();
910 boolean_type.Add(ToBooleanStub::BOOLEAN); 910 boolean_type.Add(ToBooleanStub::BOOLEAN);
911 HBranch* branch = builder()->New<HBranch>( 911 HBranch* branch = builder()->New<HBranch>(
912 constant_false, boolean_type, first_true_block_, first_false_block_); 912 constant_false, boolean_type, first_true_block_, first_false_block_);
913 builder()->FinishCurrentBlock(branch); 913 builder()->FinishCurrentBlock(branch);
914 } 914 }
915 builder()->set_current_block(first_true_block_); 915 builder()->set_current_block(first_true_block_);
916 pending_merge_block_ = true; 916 pending_merge_block_ = true;
917 } 917 }
918 918
919 919
920 void HGraphBuilder::IfBuilder::Else() { 920 void HGraphBuilder::IfBuilder::Else() {
921 ASSERT(did_then_); 921 DCHECK(did_then_);
922 ASSERT(!captured_); 922 DCHECK(!captured_);
923 ASSERT(!finished_); 923 DCHECK(!finished_);
924 AddMergeAtJoinBlock(false); 924 AddMergeAtJoinBlock(false);
925 builder()->set_current_block(first_false_block_); 925 builder()->set_current_block(first_false_block_);
926 pending_merge_block_ = true; 926 pending_merge_block_ = true;
927 did_else_ = true; 927 did_else_ = true;
928 } 928 }
929 929
930 930
931 void HGraphBuilder::IfBuilder::Deopt(const char* reason) { 931 void HGraphBuilder::IfBuilder::Deopt(const char* reason) {
932 ASSERT(did_then_); 932 DCHECK(did_then_);
933 builder()->Add<HDeoptimize>(reason, Deoptimizer::EAGER); 933 builder()->Add<HDeoptimize>(reason, Deoptimizer::EAGER);
934 AddMergeAtJoinBlock(true); 934 AddMergeAtJoinBlock(true);
935 } 935 }
936 936
937 937
938 void HGraphBuilder::IfBuilder::Return(HValue* value) { 938 void HGraphBuilder::IfBuilder::Return(HValue* value) {
939 HValue* parameter_count = builder()->graph()->GetConstantMinus1(); 939 HValue* parameter_count = builder()->graph()->GetConstantMinus1();
940 builder()->FinishExitCurrentBlock( 940 builder()->FinishExitCurrentBlock(
941 builder()->New<HReturn>(value, parameter_count)); 941 builder()->New<HReturn>(value, parameter_count));
942 AddMergeAtJoinBlock(false); 942 AddMergeAtJoinBlock(false);
943 } 943 }
944 944
945 945
946 void HGraphBuilder::IfBuilder::AddMergeAtJoinBlock(bool deopt) { 946 void HGraphBuilder::IfBuilder::AddMergeAtJoinBlock(bool deopt) {
947 if (!pending_merge_block_) return; 947 if (!pending_merge_block_) return;
948 HBasicBlock* block = builder()->current_block(); 948 HBasicBlock* block = builder()->current_block();
949 ASSERT(block == NULL || !block->IsFinished()); 949 DCHECK(block == NULL || !block->IsFinished());
950 MergeAtJoinBlock* record = new (builder()->zone()) 950 MergeAtJoinBlock* record = new (builder()->zone())
951 MergeAtJoinBlock(block, deopt, merge_at_join_blocks_); 951 MergeAtJoinBlock(block, deopt, merge_at_join_blocks_);
952 merge_at_join_blocks_ = record; 952 merge_at_join_blocks_ = record;
953 if (block != NULL) { 953 if (block != NULL) {
954 ASSERT(block->end() == NULL); 954 DCHECK(block->end() == NULL);
955 if (deopt) { 955 if (deopt) {
956 normal_merge_at_join_block_count_++; 956 normal_merge_at_join_block_count_++;
957 } else { 957 } else {
958 deopt_merge_at_join_block_count_++; 958 deopt_merge_at_join_block_count_++;
959 } 959 }
960 } 960 }
961 builder()->set_current_block(NULL); 961 builder()->set_current_block(NULL);
962 pending_merge_block_ = false; 962 pending_merge_block_ = false;
963 } 963 }
964 964
965 965
966 void HGraphBuilder::IfBuilder::Finish() { 966 void HGraphBuilder::IfBuilder::Finish() {
967 ASSERT(!finished_); 967 DCHECK(!finished_);
968 if (!did_then_) { 968 if (!did_then_) {
969 Then(); 969 Then();
970 } 970 }
971 AddMergeAtJoinBlock(false); 971 AddMergeAtJoinBlock(false);
972 if (!did_else_) { 972 if (!did_else_) {
973 Else(); 973 Else();
974 AddMergeAtJoinBlock(false); 974 AddMergeAtJoinBlock(false);
975 } 975 }
976 finished_ = true; 976 finished_ = true;
977 } 977 }
978 978
979 979
980 void HGraphBuilder::IfBuilder::Finish(HBasicBlock** then_continuation, 980 void HGraphBuilder::IfBuilder::Finish(HBasicBlock** then_continuation,
981 HBasicBlock** else_continuation) { 981 HBasicBlock** else_continuation) {
982 Finish(); 982 Finish();
983 983
984 MergeAtJoinBlock* else_record = merge_at_join_blocks_; 984 MergeAtJoinBlock* else_record = merge_at_join_blocks_;
985 if (else_continuation != NULL) { 985 if (else_continuation != NULL) {
986 *else_continuation = else_record->block_; 986 *else_continuation = else_record->block_;
987 } 987 }
988 MergeAtJoinBlock* then_record = else_record->next_; 988 MergeAtJoinBlock* then_record = else_record->next_;
989 if (then_continuation != NULL) { 989 if (then_continuation != NULL) {
990 *then_continuation = then_record->block_; 990 *then_continuation = then_record->block_;
991 } 991 }
992 ASSERT(then_record->next_ == NULL); 992 DCHECK(then_record->next_ == NULL);
993 } 993 }
994 994
995 995
996 void HGraphBuilder::IfBuilder::End() { 996 void HGraphBuilder::IfBuilder::End() {
997 if (captured_) return; 997 if (captured_) return;
998 Finish(); 998 Finish();
999 999
1000 int total_merged_blocks = normal_merge_at_join_block_count_ + 1000 int total_merged_blocks = normal_merge_at_join_block_count_ +
1001 deopt_merge_at_join_block_count_; 1001 deopt_merge_at_join_block_count_;
1002 ASSERT(total_merged_blocks >= 1); 1002 DCHECK(total_merged_blocks >= 1);
1003 HBasicBlock* merge_block = 1003 HBasicBlock* merge_block =
1004 total_merged_blocks == 1 ? NULL : builder()->graph()->CreateBasicBlock(); 1004 total_merged_blocks == 1 ? NULL : builder()->graph()->CreateBasicBlock();
1005 1005
1006 // Merge non-deopt blocks first to ensure environment has right size for 1006 // Merge non-deopt blocks first to ensure environment has right size for
1007 // padding. 1007 // padding.
1008 MergeAtJoinBlock* current = merge_at_join_blocks_; 1008 MergeAtJoinBlock* current = merge_at_join_blocks_;
1009 while (current != NULL) { 1009 while (current != NULL) {
1010 if (!current->deopt_ && current->block_ != NULL) { 1010 if (!current->deopt_ && current->block_ != NULL) {
1011 // If there is only one block that makes it through to the end of the 1011 // If there is only one block that makes it through to the end of the
1012 // if, then just set it as the current block and continue rather then 1012 // if, then just set it as the current block and continue rather then
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 body_block_ = NULL; 1066 body_block_ = NULL;
1067 exit_block_ = NULL; 1067 exit_block_ = NULL;
1068 exit_trampoline_block_ = NULL; 1068 exit_trampoline_block_ = NULL;
1069 } 1069 }
1070 1070
1071 1071
1072 HValue* HGraphBuilder::LoopBuilder::BeginBody( 1072 HValue* HGraphBuilder::LoopBuilder::BeginBody(
1073 HValue* initial, 1073 HValue* initial,
1074 HValue* terminating, 1074 HValue* terminating,
1075 Token::Value token) { 1075 Token::Value token) {
1076 ASSERT(direction_ != kWhileTrue); 1076 DCHECK(direction_ != kWhileTrue);
1077 HEnvironment* env = builder_->environment(); 1077 HEnvironment* env = builder_->environment();
1078 phi_ = header_block_->AddNewPhi(env->values()->length()); 1078 phi_ = header_block_->AddNewPhi(env->values()->length());
1079 phi_->AddInput(initial); 1079 phi_->AddInput(initial);
1080 env->Push(initial); 1080 env->Push(initial);
1081 builder_->GotoNoSimulate(header_block_); 1081 builder_->GotoNoSimulate(header_block_);
1082 1082
1083 HEnvironment* body_env = env->Copy(); 1083 HEnvironment* body_env = env->Copy();
1084 HEnvironment* exit_env = env->Copy(); 1084 HEnvironment* exit_env = env->Copy();
1085 // Remove the phi from the expression stack 1085 // Remove the phi from the expression stack
1086 body_env->Pop(); 1086 body_env->Pop();
(...skipping 17 matching lines...) Expand all
1104 increment_->ClearFlag(HValue::kCanOverflow); 1104 increment_->ClearFlag(HValue::kCanOverflow);
1105 builder_->AddInstruction(increment_); 1105 builder_->AddInstruction(increment_);
1106 return increment_; 1106 return increment_;
1107 } else { 1107 } else {
1108 return phi_; 1108 return phi_;
1109 } 1109 }
1110 } 1110 }
1111 1111
1112 1112
1113 void HGraphBuilder::LoopBuilder::BeginBody(int drop_count) { 1113 void HGraphBuilder::LoopBuilder::BeginBody(int drop_count) {
1114 ASSERT(direction_ == kWhileTrue); 1114 DCHECK(direction_ == kWhileTrue);
1115 HEnvironment* env = builder_->environment(); 1115 HEnvironment* env = builder_->environment();
1116 builder_->GotoNoSimulate(header_block_); 1116 builder_->GotoNoSimulate(header_block_);
1117 builder_->set_current_block(header_block_); 1117 builder_->set_current_block(header_block_);
1118 env->Drop(drop_count); 1118 env->Drop(drop_count);
1119 } 1119 }
1120 1120
1121 1121
1122 void HGraphBuilder::LoopBuilder::Break() { 1122 void HGraphBuilder::LoopBuilder::Break() {
1123 if (exit_trampoline_block_ == NULL) { 1123 if (exit_trampoline_block_ == NULL) {
1124 // Its the first time we saw a break. 1124 // Its the first time we saw a break.
1125 if (direction_ == kWhileTrue) { 1125 if (direction_ == kWhileTrue) {
1126 HEnvironment* env = builder_->environment()->Copy(); 1126 HEnvironment* env = builder_->environment()->Copy();
1127 exit_trampoline_block_ = builder_->CreateBasicBlock(env); 1127 exit_trampoline_block_ = builder_->CreateBasicBlock(env);
1128 } else { 1128 } else {
1129 HEnvironment* env = exit_block_->last_environment()->Copy(); 1129 HEnvironment* env = exit_block_->last_environment()->Copy();
1130 exit_trampoline_block_ = builder_->CreateBasicBlock(env); 1130 exit_trampoline_block_ = builder_->CreateBasicBlock(env);
1131 builder_->GotoNoSimulate(exit_block_, exit_trampoline_block_); 1131 builder_->GotoNoSimulate(exit_block_, exit_trampoline_block_);
1132 } 1132 }
1133 } 1133 }
1134 1134
1135 builder_->GotoNoSimulate(exit_trampoline_block_); 1135 builder_->GotoNoSimulate(exit_trampoline_block_);
1136 builder_->set_current_block(NULL); 1136 builder_->set_current_block(NULL);
1137 } 1137 }
1138 1138
1139 1139
1140 void HGraphBuilder::LoopBuilder::EndBody() { 1140 void HGraphBuilder::LoopBuilder::EndBody() {
1141 ASSERT(!finished_); 1141 DCHECK(!finished_);
1142 1142
1143 if (direction_ == kPostIncrement || direction_ == kPostDecrement) { 1143 if (direction_ == kPostIncrement || direction_ == kPostDecrement) {
1144 if (direction_ == kPostIncrement) { 1144 if (direction_ == kPostIncrement) {
1145 increment_ = HAdd::New(zone(), context_, phi_, increment_amount_); 1145 increment_ = HAdd::New(zone(), context_, phi_, increment_amount_);
1146 } else { 1146 } else {
1147 increment_ = HSub::New(zone(), context_, phi_, increment_amount_); 1147 increment_ = HSub::New(zone(), context_, phi_, increment_amount_);
1148 } 1148 }
1149 increment_->ClearFlag(HValue::kCanOverflow); 1149 increment_->ClearFlag(HValue::kCanOverflow);
1150 builder_->AddInstruction(increment_); 1150 builder_->AddInstruction(increment_);
1151 } 1151 }
(...skipping 21 matching lines...) Expand all
1173 if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_); 1173 if (FLAG_hydrogen_stats) isolate()->GetHStatistics()->Initialize(info_);
1174 CompilationPhase phase("H_Block building", info_); 1174 CompilationPhase phase("H_Block building", info_);
1175 set_current_block(graph()->entry_block()); 1175 set_current_block(graph()->entry_block());
1176 if (!BuildGraph()) return NULL; 1176 if (!BuildGraph()) return NULL;
1177 graph()->FinalizeUniqueness(); 1177 graph()->FinalizeUniqueness();
1178 return graph_; 1178 return graph_;
1179 } 1179 }
1180 1180
1181 1181
1182 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { 1182 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
1183 ASSERT(current_block() != NULL); 1183 DCHECK(current_block() != NULL);
1184 ASSERT(!FLAG_hydrogen_track_positions || 1184 DCHECK(!FLAG_hydrogen_track_positions ||
1185 !position_.IsUnknown() || 1185 !position_.IsUnknown() ||
1186 !info_->IsOptimizing()); 1186 !info_->IsOptimizing());
1187 current_block()->AddInstruction(instr, source_position()); 1187 current_block()->AddInstruction(instr, source_position());
1188 if (graph()->IsInsideNoSideEffectsScope()) { 1188 if (graph()->IsInsideNoSideEffectsScope()) {
1189 instr->SetFlag(HValue::kHasNoObservableSideEffects); 1189 instr->SetFlag(HValue::kHasNoObservableSideEffects);
1190 } 1190 }
1191 return instr; 1191 return instr;
1192 } 1192 }
1193 1193
1194 1194
1195 void HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) { 1195 void HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) {
1196 ASSERT(!FLAG_hydrogen_track_positions || 1196 DCHECK(!FLAG_hydrogen_track_positions ||
1197 !info_->IsOptimizing() || 1197 !info_->IsOptimizing() ||
1198 !position_.IsUnknown()); 1198 !position_.IsUnknown());
1199 current_block()->Finish(last, source_position()); 1199 current_block()->Finish(last, source_position());
1200 if (last->IsReturn() || last->IsAbnormalExit()) { 1200 if (last->IsReturn() || last->IsAbnormalExit()) {
1201 set_current_block(NULL); 1201 set_current_block(NULL);
1202 } 1202 }
1203 } 1203 }
1204 1204
1205 1205
1206 void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) { 1206 void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) {
1207 ASSERT(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() || 1207 DCHECK(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() ||
1208 !position_.IsUnknown()); 1208 !position_.IsUnknown());
1209 current_block()->FinishExit(instruction, source_position()); 1209 current_block()->FinishExit(instruction, source_position());
1210 if (instruction->IsReturn() || instruction->IsAbnormalExit()) { 1210 if (instruction->IsReturn() || instruction->IsAbnormalExit()) {
1211 set_current_block(NULL); 1211 set_current_block(NULL);
1212 } 1212 }
1213 } 1213 }
1214 1214
1215 1215
1216 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { 1216 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) {
1217 if (FLAG_native_code_counters && counter->Enabled()) { 1217 if (FLAG_native_code_counters && counter->Enabled()) {
1218 HValue* reference = Add<HConstant>(ExternalReference(counter)); 1218 HValue* reference = Add<HConstant>(ExternalReference(counter));
1219 HValue* old_value = Add<HLoadNamedField>( 1219 HValue* old_value = Add<HLoadNamedField>(
1220 reference, static_cast<HValue*>(NULL), HObjectAccess::ForCounter()); 1220 reference, static_cast<HValue*>(NULL), HObjectAccess::ForCounter());
1221 HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1()); 1221 HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1());
1222 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow 1222 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow
1223 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), 1223 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(),
1224 new_value, STORE_TO_INITIALIZED_ENTRY); 1224 new_value, STORE_TO_INITIALIZED_ENTRY);
1225 } 1225 }
1226 } 1226 }
1227 1227
1228 1228
1229 void HGraphBuilder::AddSimulate(BailoutId id, 1229 void HGraphBuilder::AddSimulate(BailoutId id,
1230 RemovableSimulate removable) { 1230 RemovableSimulate removable) {
1231 ASSERT(current_block() != NULL); 1231 DCHECK(current_block() != NULL);
1232 ASSERT(!graph()->IsInsideNoSideEffectsScope()); 1232 DCHECK(!graph()->IsInsideNoSideEffectsScope());
1233 current_block()->AddNewSimulate(id, source_position(), removable); 1233 current_block()->AddNewSimulate(id, source_position(), removable);
1234 } 1234 }
1235 1235
1236 1236
1237 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { 1237 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
1238 HBasicBlock* b = graph()->CreateBasicBlock(); 1238 HBasicBlock* b = graph()->CreateBasicBlock();
1239 b->SetInitialEnvironment(env); 1239 b->SetInitialEnvironment(env);
1240 return b; 1240 return b;
1241 } 1241 }
1242 1242
(...skipping 24 matching lines...) Expand all
1267 1267
1268 1268
1269 void HGraphBuilder::FinishExitWithHardDeoptimization(const char* reason) { 1269 void HGraphBuilder::FinishExitWithHardDeoptimization(const char* reason) {
1270 Add<HDeoptimize>(reason, Deoptimizer::EAGER); 1270 Add<HDeoptimize>(reason, Deoptimizer::EAGER);
1271 FinishExitCurrentBlock(New<HAbnormalExit>()); 1271 FinishExitCurrentBlock(New<HAbnormalExit>());
1272 } 1272 }
1273 1273
1274 1274
1275 HValue* HGraphBuilder::BuildCheckString(HValue* string) { 1275 HValue* HGraphBuilder::BuildCheckString(HValue* string) {
1276 if (!string->type().IsString()) { 1276 if (!string->type().IsString()) {
1277 ASSERT(!string->IsConstant() || 1277 DCHECK(!string->IsConstant() ||
1278 !HConstant::cast(string)->HasStringValue()); 1278 !HConstant::cast(string)->HasStringValue());
1279 BuildCheckHeapObject(string); 1279 BuildCheckHeapObject(string);
1280 return Add<HCheckInstanceType>(string, HCheckInstanceType::IS_STRING); 1280 return Add<HCheckInstanceType>(string, HCheckInstanceType::IS_STRING);
1281 } 1281 }
1282 return string; 1282 return string;
1283 } 1283 }
1284 1284
1285 1285
1286 HValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* function) { 1286 HValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* function) {
1287 if (object->type().IsJSObject()) return object; 1287 if (object->type().IsJSObject()) return object;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 1386
1387 return environment()->Pop(); 1387 return environment()->Pop();
1388 } 1388 }
1389 1389
1390 1390
1391 void HGraphBuilder::BuildTransitionElementsKind(HValue* object, 1391 void HGraphBuilder::BuildTransitionElementsKind(HValue* object,
1392 HValue* map, 1392 HValue* map,
1393 ElementsKind from_kind, 1393 ElementsKind from_kind,
1394 ElementsKind to_kind, 1394 ElementsKind to_kind,
1395 bool is_jsarray) { 1395 bool is_jsarray) {
1396 ASSERT(!IsFastHoleyElementsKind(from_kind) || 1396 DCHECK(!IsFastHoleyElementsKind(from_kind) ||
1397 IsFastHoleyElementsKind(to_kind)); 1397 IsFastHoleyElementsKind(to_kind));
1398 1398
1399 if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) { 1399 if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) {
1400 Add<HTrapAllocationMemento>(object); 1400 Add<HTrapAllocationMemento>(object);
1401 } 1401 }
1402 1402
1403 if (!IsSimpleMapChangeTransition(from_kind, to_kind)) { 1403 if (!IsSimpleMapChangeTransition(from_kind, to_kind)) {
1404 HInstruction* elements = AddLoadElements(object); 1404 HInstruction* elements = AddLoadElements(object);
1405 1405
1406 HInstruction* empty_fixed_array = Add<HConstant>( 1406 HInstruction* empty_fixed_array = Add<HConstant>(
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
2059 HValue* right, 2059 HValue* right,
2060 HAllocationMode allocation_mode) { 2060 HAllocationMode allocation_mode) {
2061 // Determine the string instance types. 2061 // Determine the string instance types.
2062 HInstruction* left_instance_type = AddLoadStringInstanceType(left); 2062 HInstruction* left_instance_type = AddLoadStringInstanceType(left);
2063 HInstruction* right_instance_type = AddLoadStringInstanceType(right); 2063 HInstruction* right_instance_type = AddLoadStringInstanceType(right);
2064 2064
2065 // Allocate the cons string object. HAllocate does not care whether we 2065 // Allocate the cons string object. HAllocate does not care whether we
2066 // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use 2066 // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use
2067 // CONS_STRING_TYPE here. Below we decide whether the cons string is 2067 // CONS_STRING_TYPE here. Below we decide whether the cons string is
2068 // one-byte or two-byte and set the appropriate map. 2068 // one-byte or two-byte and set the appropriate map.
2069 ASSERT(HAllocate::CompatibleInstanceTypes(CONS_STRING_TYPE, 2069 DCHECK(HAllocate::CompatibleInstanceTypes(CONS_STRING_TYPE,
2070 CONS_ASCII_STRING_TYPE)); 2070 CONS_ASCII_STRING_TYPE));
2071 HAllocate* result = BuildAllocate(Add<HConstant>(ConsString::kSize), 2071 HAllocate* result = BuildAllocate(Add<HConstant>(ConsString::kSize),
2072 HType::String(), CONS_STRING_TYPE, 2072 HType::String(), CONS_STRING_TYPE,
2073 allocation_mode); 2073 allocation_mode);
2074 2074
2075 // Compute intersection and difference of instance types. 2075 // Compute intersection and difference of instance types.
2076 HValue* anded_instance_types = AddUncasted<HBitwise>( 2076 HValue* anded_instance_types = AddUncasted<HBitwise>(
2077 Token::BIT_AND, left_instance_type, right_instance_type); 2077 Token::BIT_AND, left_instance_type, right_instance_type);
2078 HValue* xored_instance_types = AddUncasted<HBitwise>( 2078 HValue* xored_instance_types = AddUncasted<HBitwise>(
2079 Token::BIT_XOR, left_instance_type, right_instance_type); 2079 Token::BIT_XOR, left_instance_type, right_instance_type);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2137 } 2137 }
2138 2138
2139 2139
2140 void HGraphBuilder::BuildCopySeqStringChars(HValue* src, 2140 void HGraphBuilder::BuildCopySeqStringChars(HValue* src,
2141 HValue* src_offset, 2141 HValue* src_offset,
2142 String::Encoding src_encoding, 2142 String::Encoding src_encoding,
2143 HValue* dst, 2143 HValue* dst,
2144 HValue* dst_offset, 2144 HValue* dst_offset,
2145 String::Encoding dst_encoding, 2145 String::Encoding dst_encoding,
2146 HValue* length) { 2146 HValue* length) {
2147 ASSERT(dst_encoding != String::ONE_BYTE_ENCODING || 2147 DCHECK(dst_encoding != String::ONE_BYTE_ENCODING ||
2148 src_encoding == String::ONE_BYTE_ENCODING); 2148 src_encoding == String::ONE_BYTE_ENCODING);
2149 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); 2149 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement);
2150 HValue* index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT); 2150 HValue* index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT);
2151 { 2151 {
2152 HValue* src_index = AddUncasted<HAdd>(src_offset, index); 2152 HValue* src_index = AddUncasted<HAdd>(src_offset, index);
2153 HValue* value = 2153 HValue* value =
2154 AddUncasted<HSeqStringGetChar>(src_encoding, src, src_index); 2154 AddUncasted<HSeqStringGetChar>(src_encoding, src, src_index);
2155 HValue* dst_index = AddUncasted<HAdd>(dst_offset, index); 2155 HValue* dst_index = AddUncasted<HAdd>(dst_offset, index);
2156 Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value); 2156 Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value);
2157 } 2157 }
2158 loop.EndBody(); 2158 loop.EndBody();
2159 } 2159 }
2160 2160
2161 2161
2162 HValue* HGraphBuilder::BuildObjectSizeAlignment( 2162 HValue* HGraphBuilder::BuildObjectSizeAlignment(
2163 HValue* unaligned_size, int header_size) { 2163 HValue* unaligned_size, int header_size) {
2164 ASSERT((header_size & kObjectAlignmentMask) == 0); 2164 DCHECK((header_size & kObjectAlignmentMask) == 0);
2165 HValue* size = AddUncasted<HAdd>( 2165 HValue* size = AddUncasted<HAdd>(
2166 unaligned_size, Add<HConstant>(static_cast<int32_t>( 2166 unaligned_size, Add<HConstant>(static_cast<int32_t>(
2167 header_size + kObjectAlignmentMask))); 2167 header_size + kObjectAlignmentMask)));
2168 size->ClearFlag(HValue::kCanOverflow); 2168 size->ClearFlag(HValue::kCanOverflow);
2169 return AddUncasted<HBitwise>( 2169 return AddUncasted<HBitwise>(
2170 Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>( 2170 Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>(
2171 ~kObjectAlignmentMask))); 2171 ~kObjectAlignmentMask)));
2172 } 2172 }
2173 2173
2174 2174
2175 HValue* HGraphBuilder::BuildUncheckedStringAdd( 2175 HValue* HGraphBuilder::BuildUncheckedStringAdd(
2176 HValue* left, 2176 HValue* left,
2177 HValue* right, 2177 HValue* right,
2178 HAllocationMode allocation_mode) { 2178 HAllocationMode allocation_mode) {
2179 // Determine the string lengths. 2179 // Determine the string lengths.
2180 HValue* left_length = AddLoadStringLength(left); 2180 HValue* left_length = AddLoadStringLength(left);
2181 HValue* right_length = AddLoadStringLength(right); 2181 HValue* right_length = AddLoadStringLength(right);
2182 2182
2183 // Compute the combined string length. 2183 // Compute the combined string length.
2184 HValue* length = BuildAddStringLengths(left_length, right_length); 2184 HValue* length = BuildAddStringLengths(left_length, right_length);
2185 2185
2186 // Do some manual constant folding here. 2186 // Do some manual constant folding here.
2187 if (left_length->IsConstant()) { 2187 if (left_length->IsConstant()) {
2188 HConstant* c_left_length = HConstant::cast(left_length); 2188 HConstant* c_left_length = HConstant::cast(left_length);
2189 ASSERT_NE(0, c_left_length->Integer32Value()); 2189 DCHECK_NE(0, c_left_length->Integer32Value());
2190 if (c_left_length->Integer32Value() + 1 >= ConsString::kMinLength) { 2190 if (c_left_length->Integer32Value() + 1 >= ConsString::kMinLength) {
2191 // The right string contains at least one character. 2191 // The right string contains at least one character.
2192 return BuildCreateConsString(length, left, right, allocation_mode); 2192 return BuildCreateConsString(length, left, right, allocation_mode);
2193 } 2193 }
2194 } else if (right_length->IsConstant()) { 2194 } else if (right_length->IsConstant()) {
2195 HConstant* c_right_length = HConstant::cast(right_length); 2195 HConstant* c_right_length = HConstant::cast(right_length);
2196 ASSERT_NE(0, c_right_length->Integer32Value()); 2196 DCHECK_NE(0, c_right_length->Integer32Value());
2197 if (c_right_length->Integer32Value() + 1 >= ConsString::kMinLength) { 2197 if (c_right_length->Integer32Value() + 1 >= ConsString::kMinLength) {
2198 // The left string contains at least one character. 2198 // The left string contains at least one character.
2199 return BuildCreateConsString(length, left, right, allocation_mode); 2199 return BuildCreateConsString(length, left, right, allocation_mode);
2200 } 2200 }
2201 } 2201 }
2202 2202
2203 // Check if we should create a cons string. 2203 // Check if we should create a cons string.
2204 IfBuilder if_createcons(this); 2204 IfBuilder if_createcons(this);
2205 if_createcons.If<HCompareNumericAndBranch>( 2205 if_createcons.If<HCompareNumericAndBranch>(
2206 length, Add<HConstant>(ConsString::kMinLength), Token::GTE); 2206 length, Add<HConstant>(ConsString::kMinLength), Token::GTE);
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
2392 2392
2393 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 2393 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
2394 HValue* checked_object, 2394 HValue* checked_object,
2395 HValue* key, 2395 HValue* key,
2396 HValue* val, 2396 HValue* val,
2397 bool is_js_array, 2397 bool is_js_array,
2398 ElementsKind elements_kind, 2398 ElementsKind elements_kind,
2399 PropertyAccessType access_type, 2399 PropertyAccessType access_type,
2400 LoadKeyedHoleMode load_mode, 2400 LoadKeyedHoleMode load_mode,
2401 KeyedAccessStoreMode store_mode) { 2401 KeyedAccessStoreMode store_mode) {
2402 ASSERT((!IsExternalArrayElementsKind(elements_kind) && 2402 DCHECK((!IsExternalArrayElementsKind(elements_kind) &&
2403 !IsFixedTypedArrayElementsKind(elements_kind)) || 2403 !IsFixedTypedArrayElementsKind(elements_kind)) ||
2404 !is_js_array); 2404 !is_js_array);
2405 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency 2405 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency
2406 // on a HElementsTransition instruction. The flag can also be removed if the 2406 // on a HElementsTransition instruction. The flag can also be removed if the
2407 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further 2407 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further
2408 // ElementsKind transitions. Finally, the dependency can be removed for stores 2408 // ElementsKind transitions. Finally, the dependency can be removed for stores
2409 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the 2409 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the
2410 // generated store code. 2410 // generated store code.
2411 if ((elements_kind == FAST_HOLEY_ELEMENTS) || 2411 if ((elements_kind == FAST_HOLEY_ELEMENTS) ||
2412 (elements_kind == FAST_ELEMENTS && access_type == STORE)) { 2412 (elements_kind == FAST_ELEMENTS && access_type == STORE)) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2451 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( 2451 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>(
2452 key, graph()->GetConstant0(), Token::GTE); 2452 key, graph()->GetConstant0(), Token::GTE);
2453 negative_checker.Then(); 2453 negative_checker.Then();
2454 HInstruction* result = AddElementAccess( 2454 HInstruction* result = AddElementAccess(
2455 backing_store, key, val, bounds_check, elements_kind, access_type); 2455 backing_store, key, val, bounds_check, elements_kind, access_type);
2456 negative_checker.ElseDeopt("Negative key encountered"); 2456 negative_checker.ElseDeopt("Negative key encountered");
2457 negative_checker.End(); 2457 negative_checker.End();
2458 length_checker.End(); 2458 length_checker.End();
2459 return result; 2459 return result;
2460 } else { 2460 } else {
2461 ASSERT(store_mode == STANDARD_STORE); 2461 DCHECK(store_mode == STANDARD_STORE);
2462 checked_key = Add<HBoundsCheck>(key, length); 2462 checked_key = Add<HBoundsCheck>(key, length);
2463 return AddElementAccess( 2463 return AddElementAccess(
2464 backing_store, checked_key, val, 2464 backing_store, checked_key, val,
2465 checked_object, elements_kind, access_type); 2465 checked_object, elements_kind, access_type);
2466 } 2466 }
2467 } 2467 }
2468 ASSERT(fast_smi_only_elements || 2468 DCHECK(fast_smi_only_elements ||
2469 fast_elements || 2469 fast_elements ||
2470 IsFastDoubleElementsKind(elements_kind)); 2470 IsFastDoubleElementsKind(elements_kind));
2471 2471
2472 // In case val is stored into a fast smi array, assure that the value is a smi 2472 // In case val is stored into a fast smi array, assure that the value is a smi
2473 // before manipulating the backing store. Otherwise the actual store may 2473 // before manipulating the backing store. Otherwise the actual store may
2474 // deopt, leaving the backing store in an invalid state. 2474 // deopt, leaving the backing store in an invalid state.
2475 if (access_type == STORE && IsFastSmiElementsKind(elements_kind) && 2475 if (access_type == STORE && IsFastSmiElementsKind(elements_kind) &&
2476 !val->type().IsSmi()) { 2476 !val->type().IsSmi()) {
2477 val = AddUncasted<HForceRepresentation>(val, Representation::Smi()); 2477 val = AddUncasted<HForceRepresentation>(val, Representation::Smi());
2478 } 2478 }
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
2665 2665
2666 HInstruction* HGraphBuilder::AddElementAccess( 2666 HInstruction* HGraphBuilder::AddElementAccess(
2667 HValue* elements, 2667 HValue* elements,
2668 HValue* checked_key, 2668 HValue* checked_key,
2669 HValue* val, 2669 HValue* val,
2670 HValue* dependency, 2670 HValue* dependency,
2671 ElementsKind elements_kind, 2671 ElementsKind elements_kind,
2672 PropertyAccessType access_type, 2672 PropertyAccessType access_type,
2673 LoadKeyedHoleMode load_mode) { 2673 LoadKeyedHoleMode load_mode) {
2674 if (access_type == STORE) { 2674 if (access_type == STORE) {
2675 ASSERT(val != NULL); 2675 DCHECK(val != NULL);
2676 if (elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || 2676 if (elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS ||
2677 elements_kind == UINT8_CLAMPED_ELEMENTS) { 2677 elements_kind == UINT8_CLAMPED_ELEMENTS) {
2678 val = Add<HClampToUint8>(val); 2678 val = Add<HClampToUint8>(val);
2679 } 2679 }
2680 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind, 2680 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind,
2681 STORE_TO_INITIALIZED_ENTRY); 2681 STORE_TO_INITIALIZED_ENTRY);
2682 } 2682 }
2683 2683
2684 ASSERT(access_type == LOAD); 2684 DCHECK(access_type == LOAD);
2685 ASSERT(val == NULL); 2685 DCHECK(val == NULL);
2686 HLoadKeyed* load = Add<HLoadKeyed>( 2686 HLoadKeyed* load = Add<HLoadKeyed>(
2687 elements, checked_key, dependency, elements_kind, load_mode); 2687 elements, checked_key, dependency, elements_kind, load_mode);
2688 if (FLAG_opt_safe_uint32_operations && 2688 if (FLAG_opt_safe_uint32_operations &&
2689 (elements_kind == EXTERNAL_UINT32_ELEMENTS || 2689 (elements_kind == EXTERNAL_UINT32_ELEMENTS ||
2690 elements_kind == UINT32_ELEMENTS)) { 2690 elements_kind == UINT32_ELEMENTS)) {
2691 graph()->RecordUint32Instruction(load); 2691 graph()->RecordUint32Instruction(load);
2692 } 2692 }
2693 return load; 2693 return load;
2694 } 2694 }
2695 2695
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
3064 } 3064 }
3065 3065
3066 if_nil.CaptureContinuation(continuation); 3066 if_nil.CaptureContinuation(continuation);
3067 } 3067 }
3068 3068
3069 3069
3070 void HGraphBuilder::BuildCreateAllocationMemento( 3070 void HGraphBuilder::BuildCreateAllocationMemento(
3071 HValue* previous_object, 3071 HValue* previous_object,
3072 HValue* previous_object_size, 3072 HValue* previous_object_size,
3073 HValue* allocation_site) { 3073 HValue* allocation_site) {
3074 ASSERT(allocation_site != NULL); 3074 DCHECK(allocation_site != NULL);
3075 HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>( 3075 HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>(
3076 previous_object, previous_object_size, HType::HeapObject()); 3076 previous_object, previous_object_size, HType::HeapObject());
3077 AddStoreMapConstant( 3077 AddStoreMapConstant(
3078 allocation_memento, isolate()->factory()->allocation_memento_map()); 3078 allocation_memento, isolate()->factory()->allocation_memento_map());
3079 Add<HStoreNamedField>( 3079 Add<HStoreNamedField>(
3080 allocation_memento, 3080 allocation_memento,
3081 HObjectAccess::ForAllocationMementoSite(), 3081 HObjectAccess::ForAllocationMementoSite(),
3082 allocation_site); 3082 allocation_site);
3083 if (FLAG_allocation_site_pretenuring) { 3083 if (FLAG_allocation_site_pretenuring) {
3084 HValue* memento_create_count = Add<HLoadNamedField>( 3084 HValue* memento_create_count = Add<HLoadNamedField>(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
3135 3135
3136 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 3136 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
3137 ElementsKind kind, 3137 ElementsKind kind,
3138 HValue* allocation_site_payload, 3138 HValue* allocation_site_payload,
3139 HValue* constructor_function, 3139 HValue* constructor_function,
3140 AllocationSiteOverrideMode override_mode) : 3140 AllocationSiteOverrideMode override_mode) :
3141 builder_(builder), 3141 builder_(builder),
3142 kind_(kind), 3142 kind_(kind),
3143 allocation_site_payload_(allocation_site_payload), 3143 allocation_site_payload_(allocation_site_payload),
3144 constructor_function_(constructor_function) { 3144 constructor_function_(constructor_function) {
3145 ASSERT(!allocation_site_payload->IsConstant() || 3145 DCHECK(!allocation_site_payload->IsConstant() ||
3146 HConstant::cast(allocation_site_payload)->handle( 3146 HConstant::cast(allocation_site_payload)->handle(
3147 builder_->isolate())->IsAllocationSite()); 3147 builder_->isolate())->IsAllocationSite());
3148 mode_ = override_mode == DISABLE_ALLOCATION_SITES 3148 mode_ = override_mode == DISABLE_ALLOCATION_SITES
3149 ? DONT_TRACK_ALLOCATION_SITE 3149 ? DONT_TRACK_ALLOCATION_SITE
3150 : AllocationSite::GetMode(kind); 3150 : AllocationSite::GetMode(kind);
3151 } 3151 }
3152 3152
3153 3153
3154 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, 3154 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder,
3155 ElementsKind kind, 3155 ElementsKind kind,
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
3447 3447
3448 HBasicBlock* HGraph::CreateBasicBlock() { 3448 HBasicBlock* HGraph::CreateBasicBlock() {
3449 HBasicBlock* result = new(zone()) HBasicBlock(this); 3449 HBasicBlock* result = new(zone()) HBasicBlock(this);
3450 blocks_.Add(result, zone()); 3450 blocks_.Add(result, zone());
3451 return result; 3451 return result;
3452 } 3452 }
3453 3453
3454 3454
3455 void HGraph::FinalizeUniqueness() { 3455 void HGraph::FinalizeUniqueness() {
3456 DisallowHeapAllocation no_gc; 3456 DisallowHeapAllocation no_gc;
3457 ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate())); 3457 DCHECK(!OptimizingCompilerThread::IsOptimizerThread(isolate()));
3458 for (int i = 0; i < blocks()->length(); ++i) { 3458 for (int i = 0; i < blocks()->length(); ++i) {
3459 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { 3459 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) {
3460 it.Current()->FinalizeUniqueness(); 3460 it.Current()->FinalizeUniqueness();
3461 } 3461 }
3462 } 3462 }
3463 } 3463 }
3464 3464
3465 3465
3466 int HGraph::TraceInlinedFunction( 3466 int HGraph::TraceInlinedFunction(
3467 Handle<SharedFunctionInfo> shared, 3467 Handle<SharedFunctionInfo> shared,
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
3634 block->MarkAsOrdered(); 3634 block->MarkAsOrdered();
3635 3635
3636 if (block->IsLoopHeader()) { 3636 if (block->IsLoopHeader()) {
3637 kind_ = SUCCESSORS_OF_LOOP_HEADER; 3637 kind_ = SUCCESSORS_OF_LOOP_HEADER;
3638 loop_header_ = block; 3638 loop_header_ = block;
3639 InitializeSuccessors(); 3639 InitializeSuccessors();
3640 PostorderProcessor* result = Push(zone); 3640 PostorderProcessor* result = Push(zone);
3641 return result->SetupLoopMembers(zone, block, block->loop_information(), 3641 return result->SetupLoopMembers(zone, block, block->loop_information(),
3642 loop_header); 3642 loop_header);
3643 } else { 3643 } else {
3644 ASSERT(block->IsFinished()); 3644 DCHECK(block->IsFinished());
3645 kind_ = SUCCESSORS; 3645 kind_ = SUCCESSORS;
3646 loop_header_ = loop_header; 3646 loop_header_ = loop_header;
3647 InitializeSuccessors(); 3647 InitializeSuccessors();
3648 return this; 3648 return this;
3649 } 3649 }
3650 } 3650 }
3651 } 3651 }
3652 3652
3653 PostorderProcessor* SetupLoopMembers(Zone* zone, 3653 PostorderProcessor* SetupLoopMembers(Zone* zone,
3654 HBasicBlock* block, 3654 HBasicBlock* block,
(...skipping 21 matching lines...) Expand all
3676 3676
3677 // This method "allocates" a new stack frame. 3677 // This method "allocates" a new stack frame.
3678 PostorderProcessor* Push(Zone* zone) { 3678 PostorderProcessor* Push(Zone* zone) {
3679 if (child_ == NULL) { 3679 if (child_ == NULL) {
3680 child_ = new(zone) PostorderProcessor(this); 3680 child_ = new(zone) PostorderProcessor(this);
3681 } 3681 }
3682 return child_; 3682 return child_;
3683 } 3683 }
3684 3684
3685 void ClosePostorder(ZoneList<HBasicBlock*>* order, Zone* zone) { 3685 void ClosePostorder(ZoneList<HBasicBlock*>* order, Zone* zone) {
3686 ASSERT(block_->end()->FirstSuccessor() == NULL || 3686 DCHECK(block_->end()->FirstSuccessor() == NULL ||
3687 order->Contains(block_->end()->FirstSuccessor()) || 3687 order->Contains(block_->end()->FirstSuccessor()) ||
3688 block_->end()->FirstSuccessor()->IsLoopHeader()); 3688 block_->end()->FirstSuccessor()->IsLoopHeader());
3689 ASSERT(block_->end()->SecondSuccessor() == NULL || 3689 DCHECK(block_->end()->SecondSuccessor() == NULL ||
3690 order->Contains(block_->end()->SecondSuccessor()) || 3690 order->Contains(block_->end()->SecondSuccessor()) ||
3691 block_->end()->SecondSuccessor()->IsLoopHeader()); 3691 block_->end()->SecondSuccessor()->IsLoopHeader());
3692 order->Add(block_, zone); 3692 order->Add(block_, zone);
3693 } 3693 }
3694 3694
3695 // This method is the basic block to walk up the stack. 3695 // This method is the basic block to walk up the stack.
3696 PostorderProcessor* Pop(Zone* zone, 3696 PostorderProcessor* Pop(Zone* zone,
3697 ZoneList<HBasicBlock*>* order) { 3697 ZoneList<HBasicBlock*>* order) {
3698 switch (kind_) { 3698 switch (kind_) {
3699 case SUCCESSORS: 3699 case SUCCESSORS:
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
3817 HSuccessorIterator successor_iterator; 3817 HSuccessorIterator successor_iterator;
3818 }; 3818 };
3819 3819
3820 3820
3821 void HGraph::OrderBlocks() { 3821 void HGraph::OrderBlocks() {
3822 CompilationPhase phase("H_Block ordering", info()); 3822 CompilationPhase phase("H_Block ordering", info());
3823 3823
3824 #ifdef DEBUG 3824 #ifdef DEBUG
3825 // Initially the blocks must not be ordered. 3825 // Initially the blocks must not be ordered.
3826 for (int i = 0; i < blocks_.length(); ++i) { 3826 for (int i = 0; i < blocks_.length(); ++i) {
3827 ASSERT(!blocks_[i]->IsOrdered()); 3827 DCHECK(!blocks_[i]->IsOrdered());
3828 } 3828 }
3829 #endif 3829 #endif
3830 3830
3831 PostorderProcessor* postorder = 3831 PostorderProcessor* postorder =
3832 PostorderProcessor::CreateEntryProcessor(zone(), blocks_[0]); 3832 PostorderProcessor::CreateEntryProcessor(zone(), blocks_[0]);
3833 blocks_.Rewind(0); 3833 blocks_.Rewind(0);
3834 while (postorder) { 3834 while (postorder) {
3835 postorder = postorder->PerformStep(zone(), &blocks_); 3835 postorder = postorder->PerformStep(zone(), &blocks_);
3836 } 3836 }
3837 3837
3838 #ifdef DEBUG 3838 #ifdef DEBUG
3839 // Now all blocks must be marked as ordered. 3839 // Now all blocks must be marked as ordered.
3840 for (int i = 0; i < blocks_.length(); ++i) { 3840 for (int i = 0; i < blocks_.length(); ++i) {
3841 ASSERT(blocks_[i]->IsOrdered()); 3841 DCHECK(blocks_[i]->IsOrdered());
3842 } 3842 }
3843 #endif 3843 #endif
3844 3844
3845 // Reverse block list and assign block IDs. 3845 // Reverse block list and assign block IDs.
3846 for (int i = 0, j = blocks_.length(); --j >= i; ++i) { 3846 for (int i = 0, j = blocks_.length(); --j >= i; ++i) {
3847 HBasicBlock* bi = blocks_[i]; 3847 HBasicBlock* bi = blocks_[i];
3848 HBasicBlock* bj = blocks_[j]; 3848 HBasicBlock* bj = blocks_[j];
3849 bi->set_block_id(j); 3849 bi->set_block_id(j);
3850 bj->set_block_id(i); 3850 bj->set_block_id(i);
3851 blocks_[i] = bj; 3851 blocks_[i] = bj;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
3978 3978
3979 // Implementation of utility classes to represent an expression's context in 3979 // Implementation of utility classes to represent an expression's context in
3980 // the AST. 3980 // the AST.
3981 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) 3981 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind)
3982 : owner_(owner), 3982 : owner_(owner),
3983 kind_(kind), 3983 kind_(kind),
3984 outer_(owner->ast_context()), 3984 outer_(owner->ast_context()),
3985 for_typeof_(false) { 3985 for_typeof_(false) {
3986 owner->set_ast_context(this); // Push. 3986 owner->set_ast_context(this); // Push.
3987 #ifdef DEBUG 3987 #ifdef DEBUG
3988 ASSERT(owner->environment()->frame_type() == JS_FUNCTION); 3988 DCHECK(owner->environment()->frame_type() == JS_FUNCTION);
3989 original_length_ = owner->environment()->length(); 3989 original_length_ = owner->environment()->length();
3990 #endif 3990 #endif
3991 } 3991 }
3992 3992
3993 3993
3994 AstContext::~AstContext() { 3994 AstContext::~AstContext() {
3995 owner_->set_ast_context(outer_); // Pop. 3995 owner_->set_ast_context(outer_); // Pop.
3996 } 3996 }
3997 3997
3998 3998
3999 EffectContext::~EffectContext() { 3999 EffectContext::~EffectContext() {
4000 ASSERT(owner()->HasStackOverflow() || 4000 DCHECK(owner()->HasStackOverflow() ||
4001 owner()->current_block() == NULL || 4001 owner()->current_block() == NULL ||
4002 (owner()->environment()->length() == original_length_ && 4002 (owner()->environment()->length() == original_length_ &&
4003 owner()->environment()->frame_type() == JS_FUNCTION)); 4003 owner()->environment()->frame_type() == JS_FUNCTION));
4004 } 4004 }
4005 4005
4006 4006
4007 ValueContext::~ValueContext() { 4007 ValueContext::~ValueContext() {
4008 ASSERT(owner()->HasStackOverflow() || 4008 DCHECK(owner()->HasStackOverflow() ||
4009 owner()->current_block() == NULL || 4009 owner()->current_block() == NULL ||
4010 (owner()->environment()->length() == original_length_ + 1 && 4010 (owner()->environment()->length() == original_length_ + 1 &&
4011 owner()->environment()->frame_type() == JS_FUNCTION)); 4011 owner()->environment()->frame_type() == JS_FUNCTION));
4012 } 4012 }
4013 4013
4014 4014
4015 void EffectContext::ReturnValue(HValue* value) { 4015 void EffectContext::ReturnValue(HValue* value) {
4016 // The value is simply ignored. 4016 // The value is simply ignored.
4017 } 4017 }
4018 4018
4019 4019
4020 void ValueContext::ReturnValue(HValue* value) { 4020 void ValueContext::ReturnValue(HValue* value) {
4021 // The value is tracked in the bailout environment, and communicated 4021 // The value is tracked in the bailout environment, and communicated
4022 // through the environment as the result of the expression. 4022 // through the environment as the result of the expression.
4023 if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) { 4023 if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) {
4024 owner()->Bailout(kBadValueContextForArgumentsValue); 4024 owner()->Bailout(kBadValueContextForArgumentsValue);
4025 } 4025 }
4026 owner()->Push(value); 4026 owner()->Push(value);
4027 } 4027 }
4028 4028
4029 4029
4030 void TestContext::ReturnValue(HValue* value) { 4030 void TestContext::ReturnValue(HValue* value) {
4031 BuildBranch(value); 4031 BuildBranch(value);
4032 } 4032 }
4033 4033
4034 4034
4035 void EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 4035 void EffectContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
4036 ASSERT(!instr->IsControlInstruction()); 4036 DCHECK(!instr->IsControlInstruction());
4037 owner()->AddInstruction(instr); 4037 owner()->AddInstruction(instr);
4038 if (instr->HasObservableSideEffects()) { 4038 if (instr->HasObservableSideEffects()) {
4039 owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 4039 owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
4040 } 4040 }
4041 } 4041 }
4042 4042
4043 4043
4044 void EffectContext::ReturnControl(HControlInstruction* instr, 4044 void EffectContext::ReturnControl(HControlInstruction* instr,
4045 BailoutId ast_id) { 4045 BailoutId ast_id) {
4046 ASSERT(!instr->HasObservableSideEffects()); 4046 DCHECK(!instr->HasObservableSideEffects());
4047 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 4047 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
4048 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 4048 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
4049 instr->SetSuccessorAt(0, empty_true); 4049 instr->SetSuccessorAt(0, empty_true);
4050 instr->SetSuccessorAt(1, empty_false); 4050 instr->SetSuccessorAt(1, empty_false);
4051 owner()->FinishCurrentBlock(instr); 4051 owner()->FinishCurrentBlock(instr);
4052 HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id); 4052 HBasicBlock* join = owner()->CreateJoin(empty_true, empty_false, ast_id);
4053 owner()->set_current_block(join); 4053 owner()->set_current_block(join);
4054 } 4054 }
4055 4055
4056 4056
4057 void EffectContext::ReturnContinuation(HIfContinuation* continuation, 4057 void EffectContext::ReturnContinuation(HIfContinuation* continuation,
4058 BailoutId ast_id) { 4058 BailoutId ast_id) {
4059 HBasicBlock* true_branch = NULL; 4059 HBasicBlock* true_branch = NULL;
4060 HBasicBlock* false_branch = NULL; 4060 HBasicBlock* false_branch = NULL;
4061 continuation->Continue(&true_branch, &false_branch); 4061 continuation->Continue(&true_branch, &false_branch);
4062 if (!continuation->IsTrueReachable()) { 4062 if (!continuation->IsTrueReachable()) {
4063 owner()->set_current_block(false_branch); 4063 owner()->set_current_block(false_branch);
4064 } else if (!continuation->IsFalseReachable()) { 4064 } else if (!continuation->IsFalseReachable()) {
4065 owner()->set_current_block(true_branch); 4065 owner()->set_current_block(true_branch);
4066 } else { 4066 } else {
4067 HBasicBlock* join = owner()->CreateJoin(true_branch, false_branch, ast_id); 4067 HBasicBlock* join = owner()->CreateJoin(true_branch, false_branch, ast_id);
4068 owner()->set_current_block(join); 4068 owner()->set_current_block(join);
4069 } 4069 }
4070 } 4070 }
4071 4071
4072 4072
4073 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 4073 void ValueContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
4074 ASSERT(!instr->IsControlInstruction()); 4074 DCHECK(!instr->IsControlInstruction());
4075 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 4075 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
4076 return owner()->Bailout(kBadValueContextForArgumentsObjectValue); 4076 return owner()->Bailout(kBadValueContextForArgumentsObjectValue);
4077 } 4077 }
4078 owner()->AddInstruction(instr); 4078 owner()->AddInstruction(instr);
4079 owner()->Push(instr); 4079 owner()->Push(instr);
4080 if (instr->HasObservableSideEffects()) { 4080 if (instr->HasObservableSideEffects()) {
4081 owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 4081 owner()->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
4082 } 4082 }
4083 } 4083 }
4084 4084
4085 4085
4086 void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 4086 void ValueContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
4087 ASSERT(!instr->HasObservableSideEffects()); 4087 DCHECK(!instr->HasObservableSideEffects());
4088 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) { 4088 if (!arguments_allowed() && instr->CheckFlag(HValue::kIsArguments)) {
4089 return owner()->Bailout(kBadValueContextForArgumentsObjectValue); 4089 return owner()->Bailout(kBadValueContextForArgumentsObjectValue);
4090 } 4090 }
4091 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock(); 4091 HBasicBlock* materialize_false = owner()->graph()->CreateBasicBlock();
4092 HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock(); 4092 HBasicBlock* materialize_true = owner()->graph()->CreateBasicBlock();
4093 instr->SetSuccessorAt(0, materialize_true); 4093 instr->SetSuccessorAt(0, materialize_true);
4094 instr->SetSuccessorAt(1, materialize_false); 4094 instr->SetSuccessorAt(1, materialize_false);
4095 owner()->FinishCurrentBlock(instr); 4095 owner()->FinishCurrentBlock(instr);
4096 owner()->set_current_block(materialize_true); 4096 owner()->set_current_block(materialize_true);
4097 owner()->Push(owner()->graph()->GetConstantTrue()); 4097 owner()->Push(owner()->graph()->GetConstantTrue());
(...skipping 22 matching lines...) Expand all
4120 } 4120 }
4121 if (continuation->TrueAndFalseReachable()) { 4121 if (continuation->TrueAndFalseReachable()) {
4122 HBasicBlock* join = 4122 HBasicBlock* join =
4123 owner()->CreateJoin(materialize_true, materialize_false, ast_id); 4123 owner()->CreateJoin(materialize_true, materialize_false, ast_id);
4124 owner()->set_current_block(join); 4124 owner()->set_current_block(join);
4125 } 4125 }
4126 } 4126 }
4127 4127
4128 4128
4129 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) { 4129 void TestContext::ReturnInstruction(HInstruction* instr, BailoutId ast_id) {
4130 ASSERT(!instr->IsControlInstruction()); 4130 DCHECK(!instr->IsControlInstruction());
4131 HOptimizedGraphBuilder* builder = owner(); 4131 HOptimizedGraphBuilder* builder = owner();
4132 builder->AddInstruction(instr); 4132 builder->AddInstruction(instr);
4133 // We expect a simulate after every expression with side effects, though 4133 // We expect a simulate after every expression with side effects, though
4134 // this one isn't actually needed (and wouldn't work if it were targeted). 4134 // this one isn't actually needed (and wouldn't work if it were targeted).
4135 if (instr->HasObservableSideEffects()) { 4135 if (instr->HasObservableSideEffects()) {
4136 builder->Push(instr); 4136 builder->Push(instr);
4137 builder->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 4137 builder->Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
4138 builder->Pop(); 4138 builder->Pop();
4139 } 4139 }
4140 BuildBranch(instr); 4140 BuildBranch(instr);
4141 } 4141 }
4142 4142
4143 4143
4144 void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) { 4144 void TestContext::ReturnControl(HControlInstruction* instr, BailoutId ast_id) {
4145 ASSERT(!instr->HasObservableSideEffects()); 4145 DCHECK(!instr->HasObservableSideEffects());
4146 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock(); 4146 HBasicBlock* empty_true = owner()->graph()->CreateBasicBlock();
4147 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock(); 4147 HBasicBlock* empty_false = owner()->graph()->CreateBasicBlock();
4148 instr->SetSuccessorAt(0, empty_true); 4148 instr->SetSuccessorAt(0, empty_true);
4149 instr->SetSuccessorAt(1, empty_false); 4149 instr->SetSuccessorAt(1, empty_false);
4150 owner()->FinishCurrentBlock(instr); 4150 owner()->FinishCurrentBlock(instr);
4151 owner()->Goto(empty_true, if_true(), owner()->function_state()); 4151 owner()->Goto(empty_true, if_true(), owner()->function_state());
4152 owner()->Goto(empty_false, if_false(), owner()->function_state()); 4152 owner()->Goto(empty_false, if_false(), owner()->function_state());
4153 owner()->set_current_block(NULL); 4153 owner()->set_current_block(NULL);
4154 } 4154 }
4155 4155
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
4300 if (current_block() != NULL) { 4300 if (current_block() != NULL) {
4301 Add<HReturn>(graph()->GetConstantUndefined()); 4301 Add<HReturn>(graph()->GetConstantUndefined());
4302 set_current_block(NULL); 4302 set_current_block(NULL);
4303 } 4303 }
4304 4304
4305 // If the checksum of the number of type info changes is the same as the 4305 // If the checksum of the number of type info changes is the same as the
4306 // last time this function was compiled, then this recompile is likely not 4306 // last time this function was compiled, then this recompile is likely not
4307 // due to missing/inadequate type feedback, but rather too aggressive 4307 // due to missing/inadequate type feedback, but rather too aggressive
4308 // optimization. Disable optimistic LICM in that case. 4308 // optimization. Disable optimistic LICM in that case.
4309 Handle<Code> unoptimized_code(current_info()->shared_info()->code()); 4309 Handle<Code> unoptimized_code(current_info()->shared_info()->code());
4310 ASSERT(unoptimized_code->kind() == Code::FUNCTION); 4310 DCHECK(unoptimized_code->kind() == Code::FUNCTION);
4311 Handle<TypeFeedbackInfo> type_info( 4311 Handle<TypeFeedbackInfo> type_info(
4312 TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); 4312 TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info()));
4313 int checksum = type_info->own_type_change_checksum(); 4313 int checksum = type_info->own_type_change_checksum();
4314 int composite_checksum = graph()->update_type_change_checksum(checksum); 4314 int composite_checksum = graph()->update_type_change_checksum(checksum);
4315 graph()->set_use_optimistic_licm( 4315 graph()->set_use_optimistic_licm(
4316 !type_info->matches_inlined_type_change_checksum(composite_checksum)); 4316 !type_info->matches_inlined_type_change_checksum(composite_checksum));
4317 type_info->set_inlined_type_change_checksum(composite_checksum); 4317 type_info->set_inlined_type_change_checksum(composite_checksum);
4318 4318
4319 // Perform any necessary OSR-specific cleanups or changes to the graph. 4319 // Perform any necessary OSR-specific cleanups or changes to the graph.
4320 osr()->FinishGraph(); 4320 osr()->FinishGraph();
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
4414 4414
4415 void HGraph::RestoreActualValues() { 4415 void HGraph::RestoreActualValues() {
4416 HPhase phase("H_Restore actual values", this); 4416 HPhase phase("H_Restore actual values", this);
4417 4417
4418 for (int block_index = 0; block_index < blocks()->length(); block_index++) { 4418 for (int block_index = 0; block_index < blocks()->length(); block_index++) {
4419 HBasicBlock* block = blocks()->at(block_index); 4419 HBasicBlock* block = blocks()->at(block_index);
4420 4420
4421 #ifdef DEBUG 4421 #ifdef DEBUG
4422 for (int i = 0; i < block->phis()->length(); i++) { 4422 for (int i = 0; i < block->phis()->length(); i++) {
4423 HPhi* phi = block->phis()->at(i); 4423 HPhi* phi = block->phis()->at(i);
4424 ASSERT(phi->ActualValue() == phi); 4424 DCHECK(phi->ActualValue() == phi);
4425 } 4425 }
4426 #endif 4426 #endif
4427 4427
4428 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { 4428 for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
4429 HInstruction* instruction = it.Current(); 4429 HInstruction* instruction = it.Current();
4430 if (instruction->ActualValue() == instruction) continue; 4430 if (instruction->ActualValue() == instruction) continue;
4431 if (instruction->CheckFlag(HValue::kIsDead)) { 4431 if (instruction->CheckFlag(HValue::kIsDead)) {
4432 // The instruction was marked as deleted but left in the graph 4432 // The instruction was marked as deleted but left in the graph
4433 // as a control flow dependency point for subsequent 4433 // as a control flow dependency point for subsequent
4434 // instructions. 4434 // instructions.
4435 instruction->DeleteAndReplaceWith(instruction->ActualValue()); 4435 instruction->DeleteAndReplaceWith(instruction->ActualValue());
4436 } else { 4436 } else {
4437 ASSERT(instruction->IsInformativeDefinition()); 4437 DCHECK(instruction->IsInformativeDefinition());
4438 if (instruction->IsPurelyInformativeDefinition()) { 4438 if (instruction->IsPurelyInformativeDefinition()) {
4439 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand()); 4439 instruction->DeleteAndReplaceWith(instruction->RedefinedOperand());
4440 } else { 4440 } else {
4441 instruction->ReplaceAllUsesWith(instruction->ActualValue()); 4441 instruction->ReplaceAllUsesWith(instruction->ActualValue());
4442 } 4442 }
4443 } 4443 }
4444 } 4444 }
4445 } 4445 }
4446 } 4446 }
4447 4447
(...skipping 19 matching lines...) Expand all
4467 } 4467 }
4468 4468
4469 4469
4470 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) { 4470 void HOptimizedGraphBuilder::SetUpScope(Scope* scope) {
4471 // First special is HContext. 4471 // First special is HContext.
4472 HInstruction* context = Add<HContext>(); 4472 HInstruction* context = Add<HContext>();
4473 environment()->BindContext(context); 4473 environment()->BindContext(context);
4474 4474
4475 // Create an arguments object containing the initial parameters. Set the 4475 // Create an arguments object containing the initial parameters. Set the
4476 // initial values of parameters including "this" having parameter index 0. 4476 // initial values of parameters including "this" having parameter index 0.
4477 ASSERT_EQ(scope->num_parameters() + 1, environment()->parameter_count()); 4477 DCHECK_EQ(scope->num_parameters() + 1, environment()->parameter_count());
4478 HArgumentsObject* arguments_object = 4478 HArgumentsObject* arguments_object =
4479 New<HArgumentsObject>(environment()->parameter_count()); 4479 New<HArgumentsObject>(environment()->parameter_count());
4480 for (int i = 0; i < environment()->parameter_count(); ++i) { 4480 for (int i = 0; i < environment()->parameter_count(); ++i) {
4481 HInstruction* parameter = Add<HParameter>(i); 4481 HInstruction* parameter = Add<HParameter>(i);
4482 arguments_object->AddArgument(parameter, zone()); 4482 arguments_object->AddArgument(parameter, zone());
4483 environment()->Bind(i, parameter); 4483 environment()->Bind(i, parameter);
4484 } 4484 }
4485 AddInstruction(arguments_object); 4485 AddInstruction(arguments_object);
4486 graph()->SetArgumentsObject(arguments_object); 4486 graph()->SetArgumentsObject(arguments_object);
4487 4487
(...skipping 21 matching lines...) Expand all
4509 void HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) { 4509 void HOptimizedGraphBuilder::VisitStatements(ZoneList<Statement*>* statements) {
4510 for (int i = 0; i < statements->length(); i++) { 4510 for (int i = 0; i < statements->length(); i++) {
4511 Statement* stmt = statements->at(i); 4511 Statement* stmt = statements->at(i);
4512 CHECK_ALIVE(Visit(stmt)); 4512 CHECK_ALIVE(Visit(stmt));
4513 if (stmt->IsJump()) break; 4513 if (stmt->IsJump()) break;
4514 } 4514 }
4515 } 4515 }
4516 4516
4517 4517
4518 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) { 4518 void HOptimizedGraphBuilder::VisitBlock(Block* stmt) {
4519 ASSERT(!HasStackOverflow()); 4519 DCHECK(!HasStackOverflow());
4520 ASSERT(current_block() != NULL); 4520 DCHECK(current_block() != NULL);
4521 ASSERT(current_block()->HasPredecessor()); 4521 DCHECK(current_block()->HasPredecessor());
4522 4522
4523 Scope* outer_scope = scope(); 4523 Scope* outer_scope = scope();
4524 Scope* scope = stmt->scope(); 4524 Scope* scope = stmt->scope();
4525 BreakAndContinueInfo break_info(stmt, outer_scope); 4525 BreakAndContinueInfo break_info(stmt, outer_scope);
4526 4526
4527 { BreakAndContinueScope push(&break_info, this); 4527 { BreakAndContinueScope push(&break_info, this);
4528 if (scope != NULL) { 4528 if (scope != NULL) {
4529 // Load the function object. 4529 // Load the function object.
4530 Scope* declaration_scope = scope->DeclarationScope(); 4530 Scope* declaration_scope = scope->DeclarationScope();
4531 HInstruction* function; 4531 HInstruction* function;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
4569 if (break_block != NULL) { 4569 if (break_block != NULL) {
4570 if (current_block() != NULL) Goto(break_block); 4570 if (current_block() != NULL) Goto(break_block);
4571 break_block->SetJoinId(stmt->ExitId()); 4571 break_block->SetJoinId(stmt->ExitId());
4572 set_current_block(break_block); 4572 set_current_block(break_block);
4573 } 4573 }
4574 } 4574 }
4575 4575
4576 4576
4577 void HOptimizedGraphBuilder::VisitExpressionStatement( 4577 void HOptimizedGraphBuilder::VisitExpressionStatement(
4578 ExpressionStatement* stmt) { 4578 ExpressionStatement* stmt) {
4579 ASSERT(!HasStackOverflow()); 4579 DCHECK(!HasStackOverflow());
4580 ASSERT(current_block() != NULL); 4580 DCHECK(current_block() != NULL);
4581 ASSERT(current_block()->HasPredecessor()); 4581 DCHECK(current_block()->HasPredecessor());
4582 VisitForEffect(stmt->expression()); 4582 VisitForEffect(stmt->expression());
4583 } 4583 }
4584 4584
4585 4585
4586 void HOptimizedGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) { 4586 void HOptimizedGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) {
4587 ASSERT(!HasStackOverflow()); 4587 DCHECK(!HasStackOverflow());
4588 ASSERT(current_block() != NULL); 4588 DCHECK(current_block() != NULL);
4589 ASSERT(current_block()->HasPredecessor()); 4589 DCHECK(current_block()->HasPredecessor());
4590 } 4590 }
4591 4591
4592 4592
4593 void HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) { 4593 void HOptimizedGraphBuilder::VisitIfStatement(IfStatement* stmt) {
4594 ASSERT(!HasStackOverflow()); 4594 DCHECK(!HasStackOverflow());
4595 ASSERT(current_block() != NULL); 4595 DCHECK(current_block() != NULL);
4596 ASSERT(current_block()->HasPredecessor()); 4596 DCHECK(current_block()->HasPredecessor());
4597 if (stmt->condition()->ToBooleanIsTrue()) { 4597 if (stmt->condition()->ToBooleanIsTrue()) {
4598 Add<HSimulate>(stmt->ThenId()); 4598 Add<HSimulate>(stmt->ThenId());
4599 Visit(stmt->then_statement()); 4599 Visit(stmt->then_statement());
4600 } else if (stmt->condition()->ToBooleanIsFalse()) { 4600 } else if (stmt->condition()->ToBooleanIsFalse()) {
4601 Add<HSimulate>(stmt->ElseId()); 4601 Add<HSimulate>(stmt->ElseId());
4602 Visit(stmt->else_statement()); 4602 Visit(stmt->else_statement());
4603 } else { 4603 } else {
4604 HBasicBlock* cond_true = graph()->CreateBasicBlock(); 4604 HBasicBlock* cond_true = graph()->CreateBasicBlock();
4605 HBasicBlock* cond_false = graph()->CreateBasicBlock(); 4605 HBasicBlock* cond_false = graph()->CreateBasicBlock();
4606 CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false)); 4606 CHECK_BAILOUT(VisitForControl(stmt->condition(), cond_true, cond_false));
(...skipping 26 matching lines...) Expand all
4633 BreakableStatement* stmt, 4633 BreakableStatement* stmt,
4634 BreakType type, 4634 BreakType type,
4635 Scope** scope, 4635 Scope** scope,
4636 int* drop_extra) { 4636 int* drop_extra) {
4637 *drop_extra = 0; 4637 *drop_extra = 0;
4638 BreakAndContinueScope* current = this; 4638 BreakAndContinueScope* current = this;
4639 while (current != NULL && current->info()->target() != stmt) { 4639 while (current != NULL && current->info()->target() != stmt) {
4640 *drop_extra += current->info()->drop_extra(); 4640 *drop_extra += current->info()->drop_extra();
4641 current = current->next(); 4641 current = current->next();
4642 } 4642 }
4643 ASSERT(current != NULL); // Always found (unless stack is malformed). 4643 DCHECK(current != NULL); // Always found (unless stack is malformed).
4644 *scope = current->info()->scope(); 4644 *scope = current->info()->scope();
4645 4645
4646 if (type == BREAK) { 4646 if (type == BREAK) {
4647 *drop_extra += current->info()->drop_extra(); 4647 *drop_extra += current->info()->drop_extra();
4648 } 4648 }
4649 4649
4650 HBasicBlock* block = NULL; 4650 HBasicBlock* block = NULL;
4651 switch (type) { 4651 switch (type) {
4652 case BREAK: 4652 case BREAK:
4653 block = current->info()->break_block(); 4653 block = current->info()->break_block();
(...skipping 11 matching lines...) Expand all
4665 } 4665 }
4666 break; 4666 break;
4667 } 4667 }
4668 4668
4669 return block; 4669 return block;
4670 } 4670 }
4671 4671
4672 4672
4673 void HOptimizedGraphBuilder::VisitContinueStatement( 4673 void HOptimizedGraphBuilder::VisitContinueStatement(
4674 ContinueStatement* stmt) { 4674 ContinueStatement* stmt) {
4675 ASSERT(!HasStackOverflow()); 4675 DCHECK(!HasStackOverflow());
4676 ASSERT(current_block() != NULL); 4676 DCHECK(current_block() != NULL);
4677 ASSERT(current_block()->HasPredecessor()); 4677 DCHECK(current_block()->HasPredecessor());
4678 Scope* outer_scope = NULL; 4678 Scope* outer_scope = NULL;
4679 Scope* inner_scope = scope(); 4679 Scope* inner_scope = scope();
4680 int drop_extra = 0; 4680 int drop_extra = 0;
4681 HBasicBlock* continue_block = break_scope()->Get( 4681 HBasicBlock* continue_block = break_scope()->Get(
4682 stmt->target(), BreakAndContinueScope::CONTINUE, 4682 stmt->target(), BreakAndContinueScope::CONTINUE,
4683 &outer_scope, &drop_extra); 4683 &outer_scope, &drop_extra);
4684 HValue* context = environment()->context(); 4684 HValue* context = environment()->context();
4685 Drop(drop_extra); 4685 Drop(drop_extra);
4686 int context_pop_count = inner_scope->ContextChainLength(outer_scope); 4686 int context_pop_count = inner_scope->ContextChainLength(outer_scope);
4687 if (context_pop_count > 0) { 4687 if (context_pop_count > 0) {
4688 while (context_pop_count-- > 0) { 4688 while (context_pop_count-- > 0) {
4689 HInstruction* context_instruction = Add<HLoadNamedField>( 4689 HInstruction* context_instruction = Add<HLoadNamedField>(
4690 context, static_cast<HValue*>(NULL), 4690 context, static_cast<HValue*>(NULL),
4691 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 4691 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
4692 context = context_instruction; 4692 context = context_instruction;
4693 } 4693 }
4694 HInstruction* instr = Add<HStoreFrameContext>(context); 4694 HInstruction* instr = Add<HStoreFrameContext>(context);
4695 if (instr->HasObservableSideEffects()) { 4695 if (instr->HasObservableSideEffects()) {
4696 AddSimulate(stmt->target()->EntryId(), REMOVABLE_SIMULATE); 4696 AddSimulate(stmt->target()->EntryId(), REMOVABLE_SIMULATE);
4697 } 4697 }
4698 environment()->BindContext(context); 4698 environment()->BindContext(context);
4699 } 4699 }
4700 4700
4701 Goto(continue_block); 4701 Goto(continue_block);
4702 set_current_block(NULL); 4702 set_current_block(NULL);
4703 } 4703 }
4704 4704
4705 4705
4706 void HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) { 4706 void HOptimizedGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
4707 ASSERT(!HasStackOverflow()); 4707 DCHECK(!HasStackOverflow());
4708 ASSERT(current_block() != NULL); 4708 DCHECK(current_block() != NULL);
4709 ASSERT(current_block()->HasPredecessor()); 4709 DCHECK(current_block()->HasPredecessor());
4710 Scope* outer_scope = NULL; 4710 Scope* outer_scope = NULL;
4711 Scope* inner_scope = scope(); 4711 Scope* inner_scope = scope();
4712 int drop_extra = 0; 4712 int drop_extra = 0;
4713 HBasicBlock* break_block = break_scope()->Get( 4713 HBasicBlock* break_block = break_scope()->Get(
4714 stmt->target(), BreakAndContinueScope::BREAK, 4714 stmt->target(), BreakAndContinueScope::BREAK,
4715 &outer_scope, &drop_extra); 4715 &outer_scope, &drop_extra);
4716 HValue* context = environment()->context(); 4716 HValue* context = environment()->context();
4717 Drop(drop_extra); 4717 Drop(drop_extra);
4718 int context_pop_count = inner_scope->ContextChainLength(outer_scope); 4718 int context_pop_count = inner_scope->ContextChainLength(outer_scope);
4719 if (context_pop_count > 0) { 4719 if (context_pop_count > 0) {
4720 while (context_pop_count-- > 0) { 4720 while (context_pop_count-- > 0) {
4721 HInstruction* context_instruction = Add<HLoadNamedField>( 4721 HInstruction* context_instruction = Add<HLoadNamedField>(
4722 context, static_cast<HValue*>(NULL), 4722 context, static_cast<HValue*>(NULL),
4723 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 4723 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
4724 context = context_instruction; 4724 context = context_instruction;
4725 } 4725 }
4726 HInstruction* instr = Add<HStoreFrameContext>(context); 4726 HInstruction* instr = Add<HStoreFrameContext>(context);
4727 if (instr->HasObservableSideEffects()) { 4727 if (instr->HasObservableSideEffects()) {
4728 AddSimulate(stmt->target()->ExitId(), REMOVABLE_SIMULATE); 4728 AddSimulate(stmt->target()->ExitId(), REMOVABLE_SIMULATE);
4729 } 4729 }
4730 environment()->BindContext(context); 4730 environment()->BindContext(context);
4731 } 4731 }
4732 Goto(break_block); 4732 Goto(break_block);
4733 set_current_block(NULL); 4733 set_current_block(NULL);
4734 } 4734 }
4735 4735
4736 4736
4737 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) { 4737 void HOptimizedGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
4738 ASSERT(!HasStackOverflow()); 4738 DCHECK(!HasStackOverflow());
4739 ASSERT(current_block() != NULL); 4739 DCHECK(current_block() != NULL);
4740 ASSERT(current_block()->HasPredecessor()); 4740 DCHECK(current_block()->HasPredecessor());
4741 FunctionState* state = function_state(); 4741 FunctionState* state = function_state();
4742 AstContext* context = call_context(); 4742 AstContext* context = call_context();
4743 if (context == NULL) { 4743 if (context == NULL) {
4744 // Not an inlined return, so an actual one. 4744 // Not an inlined return, so an actual one.
4745 CHECK_ALIVE(VisitForValue(stmt->expression())); 4745 CHECK_ALIVE(VisitForValue(stmt->expression()));
4746 HValue* result = environment()->Pop(); 4746 HValue* result = environment()->Pop();
4747 Add<HReturn>(result); 4747 Add<HReturn>(result);
4748 } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { 4748 } else if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) {
4749 // Return from an inlined construct call. In a test context the return value 4749 // Return from an inlined construct call. In a test context the return value
4750 // will always evaluate to true, in a value context the return value needs 4750 // will always evaluate to true, in a value context the return value needs
4751 // to be a JSObject. 4751 // to be a JSObject.
4752 if (context->IsTest()) { 4752 if (context->IsTest()) {
4753 TestContext* test = TestContext::cast(context); 4753 TestContext* test = TestContext::cast(context);
4754 CHECK_ALIVE(VisitForEffect(stmt->expression())); 4754 CHECK_ALIVE(VisitForEffect(stmt->expression()));
4755 Goto(test->if_true(), state); 4755 Goto(test->if_true(), state);
4756 } else if (context->IsEffect()) { 4756 } else if (context->IsEffect()) {
4757 CHECK_ALIVE(VisitForEffect(stmt->expression())); 4757 CHECK_ALIVE(VisitForEffect(stmt->expression()));
4758 Goto(function_return(), state); 4758 Goto(function_return(), state);
4759 } else { 4759 } else {
4760 ASSERT(context->IsValue()); 4760 DCHECK(context->IsValue());
4761 CHECK_ALIVE(VisitForValue(stmt->expression())); 4761 CHECK_ALIVE(VisitForValue(stmt->expression()));
4762 HValue* return_value = Pop(); 4762 HValue* return_value = Pop();
4763 HValue* receiver = environment()->arguments_environment()->Lookup(0); 4763 HValue* receiver = environment()->arguments_environment()->Lookup(0);
4764 HHasInstanceTypeAndBranch* typecheck = 4764 HHasInstanceTypeAndBranch* typecheck =
4765 New<HHasInstanceTypeAndBranch>(return_value, 4765 New<HHasInstanceTypeAndBranch>(return_value,
4766 FIRST_SPEC_OBJECT_TYPE, 4766 FIRST_SPEC_OBJECT_TYPE,
4767 LAST_SPEC_OBJECT_TYPE); 4767 LAST_SPEC_OBJECT_TYPE);
4768 HBasicBlock* if_spec_object = graph()->CreateBasicBlock(); 4768 HBasicBlock* if_spec_object = graph()->CreateBasicBlock();
4769 HBasicBlock* not_spec_object = graph()->CreateBasicBlock(); 4769 HBasicBlock* not_spec_object = graph()->CreateBasicBlock();
4770 typecheck->SetSuccessorAt(0, if_spec_object); 4770 typecheck->SetSuccessorAt(0, if_spec_object);
4771 typecheck->SetSuccessorAt(1, not_spec_object); 4771 typecheck->SetSuccessorAt(1, not_spec_object);
4772 FinishCurrentBlock(typecheck); 4772 FinishCurrentBlock(typecheck);
4773 AddLeaveInlined(if_spec_object, return_value, state); 4773 AddLeaveInlined(if_spec_object, return_value, state);
4774 AddLeaveInlined(not_spec_object, receiver, state); 4774 AddLeaveInlined(not_spec_object, receiver, state);
4775 } 4775 }
4776 } else if (state->inlining_kind() == SETTER_CALL_RETURN) { 4776 } else if (state->inlining_kind() == SETTER_CALL_RETURN) {
4777 // Return from an inlined setter call. The returned value is never used, the 4777 // Return from an inlined setter call. The returned value is never used, the
4778 // value of an assignment is always the value of the RHS of the assignment. 4778 // value of an assignment is always the value of the RHS of the assignment.
4779 CHECK_ALIVE(VisitForEffect(stmt->expression())); 4779 CHECK_ALIVE(VisitForEffect(stmt->expression()));
4780 if (context->IsTest()) { 4780 if (context->IsTest()) {
4781 HValue* rhs = environment()->arguments_environment()->Lookup(1); 4781 HValue* rhs = environment()->arguments_environment()->Lookup(1);
4782 context->ReturnValue(rhs); 4782 context->ReturnValue(rhs);
4783 } else if (context->IsEffect()) { 4783 } else if (context->IsEffect()) {
4784 Goto(function_return(), state); 4784 Goto(function_return(), state);
4785 } else { 4785 } else {
4786 ASSERT(context->IsValue()); 4786 DCHECK(context->IsValue());
4787 HValue* rhs = environment()->arguments_environment()->Lookup(1); 4787 HValue* rhs = environment()->arguments_environment()->Lookup(1);
4788 AddLeaveInlined(rhs, state); 4788 AddLeaveInlined(rhs, state);
4789 } 4789 }
4790 } else { 4790 } else {
4791 // Return from a normal inlined function. Visit the subexpression in the 4791 // Return from a normal inlined function. Visit the subexpression in the
4792 // expression context of the call. 4792 // expression context of the call.
4793 if (context->IsTest()) { 4793 if (context->IsTest()) {
4794 TestContext* test = TestContext::cast(context); 4794 TestContext* test = TestContext::cast(context);
4795 VisitForControl(stmt->expression(), test->if_true(), test->if_false()); 4795 VisitForControl(stmt->expression(), test->if_true(), test->if_false());
4796 } else if (context->IsEffect()) { 4796 } else if (context->IsEffect()) {
4797 // Visit in value context and ignore the result. This is needed to keep 4797 // Visit in value context and ignore the result. This is needed to keep
4798 // environment in sync with full-codegen since some visitors (e.g. 4798 // environment in sync with full-codegen since some visitors (e.g.
4799 // VisitCountOperation) use the operand stack differently depending on 4799 // VisitCountOperation) use the operand stack differently depending on
4800 // context. 4800 // context.
4801 CHECK_ALIVE(VisitForValue(stmt->expression())); 4801 CHECK_ALIVE(VisitForValue(stmt->expression()));
4802 Pop(); 4802 Pop();
4803 Goto(function_return(), state); 4803 Goto(function_return(), state);
4804 } else { 4804 } else {
4805 ASSERT(context->IsValue()); 4805 DCHECK(context->IsValue());
4806 CHECK_ALIVE(VisitForValue(stmt->expression())); 4806 CHECK_ALIVE(VisitForValue(stmt->expression()));
4807 AddLeaveInlined(Pop(), state); 4807 AddLeaveInlined(Pop(), state);
4808 } 4808 }
4809 } 4809 }
4810 set_current_block(NULL); 4810 set_current_block(NULL);
4811 } 4811 }
4812 4812
4813 4813
4814 void HOptimizedGraphBuilder::VisitWithStatement(WithStatement* stmt) { 4814 void HOptimizedGraphBuilder::VisitWithStatement(WithStatement* stmt) {
4815 ASSERT(!HasStackOverflow()); 4815 DCHECK(!HasStackOverflow());
4816 ASSERT(current_block() != NULL); 4816 DCHECK(current_block() != NULL);
4817 ASSERT(current_block()->HasPredecessor()); 4817 DCHECK(current_block()->HasPredecessor());
4818 return Bailout(kWithStatement); 4818 return Bailout(kWithStatement);
4819 } 4819 }
4820 4820
4821 4821
4822 void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) { 4822 void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
4823 ASSERT(!HasStackOverflow()); 4823 DCHECK(!HasStackOverflow());
4824 ASSERT(current_block() != NULL); 4824 DCHECK(current_block() != NULL);
4825 ASSERT(current_block()->HasPredecessor()); 4825 DCHECK(current_block()->HasPredecessor());
4826 4826
4827 // We only optimize switch statements with a bounded number of clauses. 4827 // We only optimize switch statements with a bounded number of clauses.
4828 const int kCaseClauseLimit = 128; 4828 const int kCaseClauseLimit = 128;
4829 ZoneList<CaseClause*>* clauses = stmt->cases(); 4829 ZoneList<CaseClause*>* clauses = stmt->cases();
4830 int clause_count = clauses->length(); 4830 int clause_count = clauses->length();
4831 ZoneList<HBasicBlock*> body_blocks(clause_count, zone()); 4831 ZoneList<HBasicBlock*> body_blocks(clause_count, zone());
4832 if (clause_count > kCaseClauseLimit) { 4832 if (clause_count > kCaseClauseLimit) {
4833 return Bailout(kSwitchStatementTooManyClauses); 4833 return Bailout(kSwitchStatementTooManyClauses);
4834 } 4834 }
4835 4835
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
4927 set_current_block(break_block); 4927 set_current_block(break_block);
4928 } 4928 }
4929 } 4929 }
4930 4930
4931 4931
4932 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt, 4932 void HOptimizedGraphBuilder::VisitLoopBody(IterationStatement* stmt,
4933 HBasicBlock* loop_entry) { 4933 HBasicBlock* loop_entry) {
4934 Add<HSimulate>(stmt->StackCheckId()); 4934 Add<HSimulate>(stmt->StackCheckId());
4935 HStackCheck* stack_check = 4935 HStackCheck* stack_check =
4936 HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch)); 4936 HStackCheck::cast(Add<HStackCheck>(HStackCheck::kBackwardsBranch));
4937 ASSERT(loop_entry->IsLoopHeader()); 4937 DCHECK(loop_entry->IsLoopHeader());
4938 loop_entry->loop_information()->set_stack_check(stack_check); 4938 loop_entry->loop_information()->set_stack_check(stack_check);
4939 CHECK_BAILOUT(Visit(stmt->body())); 4939 CHECK_BAILOUT(Visit(stmt->body()));
4940 } 4940 }
4941 4941
4942 4942
4943 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) { 4943 void HOptimizedGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
4944 ASSERT(!HasStackOverflow()); 4944 DCHECK(!HasStackOverflow());
4945 ASSERT(current_block() != NULL); 4945 DCHECK(current_block() != NULL);
4946 ASSERT(current_block()->HasPredecessor()); 4946 DCHECK(current_block()->HasPredecessor());
4947 ASSERT(current_block() != NULL); 4947 DCHECK(current_block() != NULL);
4948 HBasicBlock* loop_entry = BuildLoopEntry(stmt); 4948 HBasicBlock* loop_entry = BuildLoopEntry(stmt);
4949 4949
4950 BreakAndContinueInfo break_info(stmt, scope()); 4950 BreakAndContinueInfo break_info(stmt, scope());
4951 { 4951 {
4952 BreakAndContinueScope push(&break_info, this); 4952 BreakAndContinueScope push(&break_info, this);
4953 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry)); 4953 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry));
4954 } 4954 }
4955 HBasicBlock* body_exit = 4955 HBasicBlock* body_exit =
4956 JoinContinue(stmt, current_block(), break_info.continue_block()); 4956 JoinContinue(stmt, current_block(), break_info.continue_block());
4957 HBasicBlock* loop_successor = NULL; 4957 HBasicBlock* loop_successor = NULL;
(...skipping 24 matching lines...) Expand all
4982 HBasicBlock* loop_exit = CreateLoop(stmt, 4982 HBasicBlock* loop_exit = CreateLoop(stmt,
4983 loop_entry, 4983 loop_entry,
4984 body_exit, 4984 body_exit,
4985 loop_successor, 4985 loop_successor,
4986 break_info.break_block()); 4986 break_info.break_block());
4987 set_current_block(loop_exit); 4987 set_current_block(loop_exit);
4988 } 4988 }
4989 4989
4990 4990
4991 void HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) { 4991 void HOptimizedGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
4992 ASSERT(!HasStackOverflow()); 4992 DCHECK(!HasStackOverflow());
4993 ASSERT(current_block() != NULL); 4993 DCHECK(current_block() != NULL);
4994 ASSERT(current_block()->HasPredecessor()); 4994 DCHECK(current_block()->HasPredecessor());
4995 ASSERT(current_block() != NULL); 4995 DCHECK(current_block() != NULL);
4996 HBasicBlock* loop_entry = BuildLoopEntry(stmt); 4996 HBasicBlock* loop_entry = BuildLoopEntry(stmt);
4997 4997
4998 // If the condition is constant true, do not generate a branch. 4998 // If the condition is constant true, do not generate a branch.
4999 HBasicBlock* loop_successor = NULL; 4999 HBasicBlock* loop_successor = NULL;
5000 if (!stmt->cond()->ToBooleanIsTrue()) { 5000 if (!stmt->cond()->ToBooleanIsTrue()) {
5001 HBasicBlock* body_entry = graph()->CreateBasicBlock(); 5001 HBasicBlock* body_entry = graph()->CreateBasicBlock();
5002 loop_successor = graph()->CreateBasicBlock(); 5002 loop_successor = graph()->CreateBasicBlock();
5003 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); 5003 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor));
5004 if (body_entry->HasPredecessor()) { 5004 if (body_entry->HasPredecessor()) {
5005 body_entry->SetJoinId(stmt->BodyId()); 5005 body_entry->SetJoinId(stmt->BodyId());
(...skipping 16 matching lines...) Expand all
5022 HBasicBlock* loop_exit = CreateLoop(stmt, 5022 HBasicBlock* loop_exit = CreateLoop(stmt,
5023 loop_entry, 5023 loop_entry,
5024 body_exit, 5024 body_exit,
5025 loop_successor, 5025 loop_successor,
5026 break_info.break_block()); 5026 break_info.break_block());
5027 set_current_block(loop_exit); 5027 set_current_block(loop_exit);
5028 } 5028 }
5029 5029
5030 5030
5031 void HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) { 5031 void HOptimizedGraphBuilder::VisitForStatement(ForStatement* stmt) {
5032 ASSERT(!HasStackOverflow()); 5032 DCHECK(!HasStackOverflow());
5033 ASSERT(current_block() != NULL); 5033 DCHECK(current_block() != NULL);
5034 ASSERT(current_block()->HasPredecessor()); 5034 DCHECK(current_block()->HasPredecessor());
5035 if (stmt->init() != NULL) { 5035 if (stmt->init() != NULL) {
5036 CHECK_ALIVE(Visit(stmt->init())); 5036 CHECK_ALIVE(Visit(stmt->init()));
5037 } 5037 }
5038 ASSERT(current_block() != NULL); 5038 DCHECK(current_block() != NULL);
5039 HBasicBlock* loop_entry = BuildLoopEntry(stmt); 5039 HBasicBlock* loop_entry = BuildLoopEntry(stmt);
5040 5040
5041 HBasicBlock* loop_successor = NULL; 5041 HBasicBlock* loop_successor = NULL;
5042 if (stmt->cond() != NULL) { 5042 if (stmt->cond() != NULL) {
5043 HBasicBlock* body_entry = graph()->CreateBasicBlock(); 5043 HBasicBlock* body_entry = graph()->CreateBasicBlock();
5044 loop_successor = graph()->CreateBasicBlock(); 5044 loop_successor = graph()->CreateBasicBlock();
5045 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor)); 5045 CHECK_BAILOUT(VisitForControl(stmt->cond(), body_entry, loop_successor));
5046 if (body_entry->HasPredecessor()) { 5046 if (body_entry->HasPredecessor()) {
5047 body_entry->SetJoinId(stmt->BodyId()); 5047 body_entry->SetJoinId(stmt->BodyId());
5048 set_current_block(body_entry); 5048 set_current_block(body_entry);
(...skipping 22 matching lines...) Expand all
5071 HBasicBlock* loop_exit = CreateLoop(stmt, 5071 HBasicBlock* loop_exit = CreateLoop(stmt,
5072 loop_entry, 5072 loop_entry,
5073 body_exit, 5073 body_exit,
5074 loop_successor, 5074 loop_successor,
5075 break_info.break_block()); 5075 break_info.break_block());
5076 set_current_block(loop_exit); 5076 set_current_block(loop_exit);
5077 } 5077 }
5078 5078
5079 5079
5080 void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) { 5080 void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
5081 ASSERT(!HasStackOverflow()); 5081 DCHECK(!HasStackOverflow());
5082 ASSERT(current_block() != NULL); 5082 DCHECK(current_block() != NULL);
5083 ASSERT(current_block()->HasPredecessor()); 5083 DCHECK(current_block()->HasPredecessor());
5084 5084
5085 if (!FLAG_optimize_for_in) { 5085 if (!FLAG_optimize_for_in) {
5086 return Bailout(kForInStatementOptimizationIsDisabled); 5086 return Bailout(kForInStatementOptimizationIsDisabled);
5087 } 5087 }
5088 5088
5089 if (stmt->for_in_type() != ForInStatement::FAST_FOR_IN) { 5089 if (stmt->for_in_type() != ForInStatement::FAST_FOR_IN) {
5090 return Bailout(kForInStatementIsNotFastCase); 5090 return Bailout(kForInStatementIsNotFastCase);
5091 } 5091 }
5092 5092
5093 if (!stmt->each()->IsVariableProxy() || 5093 if (!stmt->each()->IsVariableProxy() ||
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
5177 loop_entry, 5177 loop_entry,
5178 body_exit, 5178 body_exit,
5179 loop_successor, 5179 loop_successor,
5180 break_info.break_block()); 5180 break_info.break_block());
5181 5181
5182 set_current_block(loop_exit); 5182 set_current_block(loop_exit);
5183 } 5183 }
5184 5184
5185 5185
5186 void HOptimizedGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) { 5186 void HOptimizedGraphBuilder::VisitForOfStatement(ForOfStatement* stmt) {
5187 ASSERT(!HasStackOverflow()); 5187 DCHECK(!HasStackOverflow());
5188 ASSERT(current_block() != NULL); 5188 DCHECK(current_block() != NULL);
5189 ASSERT(current_block()->HasPredecessor()); 5189 DCHECK(current_block()->HasPredecessor());
5190 return Bailout(kForOfStatement); 5190 return Bailout(kForOfStatement);
5191 } 5191 }
5192 5192
5193 5193
5194 void HOptimizedGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { 5194 void HOptimizedGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
5195 ASSERT(!HasStackOverflow()); 5195 DCHECK(!HasStackOverflow());
5196 ASSERT(current_block() != NULL); 5196 DCHECK(current_block() != NULL);
5197 ASSERT(current_block()->HasPredecessor()); 5197 DCHECK(current_block()->HasPredecessor());
5198 return Bailout(kTryCatchStatement); 5198 return Bailout(kTryCatchStatement);
5199 } 5199 }
5200 5200
5201 5201
5202 void HOptimizedGraphBuilder::VisitTryFinallyStatement( 5202 void HOptimizedGraphBuilder::VisitTryFinallyStatement(
5203 TryFinallyStatement* stmt) { 5203 TryFinallyStatement* stmt) {
5204 ASSERT(!HasStackOverflow()); 5204 DCHECK(!HasStackOverflow());
5205 ASSERT(current_block() != NULL); 5205 DCHECK(current_block() != NULL);
5206 ASSERT(current_block()->HasPredecessor()); 5206 DCHECK(current_block()->HasPredecessor());
5207 return Bailout(kTryFinallyStatement); 5207 return Bailout(kTryFinallyStatement);
5208 } 5208 }
5209 5209
5210 5210
5211 void HOptimizedGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { 5211 void HOptimizedGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
5212 ASSERT(!HasStackOverflow()); 5212 DCHECK(!HasStackOverflow());
5213 ASSERT(current_block() != NULL); 5213 DCHECK(current_block() != NULL);
5214 ASSERT(current_block()->HasPredecessor()); 5214 DCHECK(current_block()->HasPredecessor());
5215 return Bailout(kDebuggerStatement); 5215 return Bailout(kDebuggerStatement);
5216 } 5216 }
5217 5217
5218 5218
5219 void HOptimizedGraphBuilder::VisitCaseClause(CaseClause* clause) { 5219 void HOptimizedGraphBuilder::VisitCaseClause(CaseClause* clause) {
5220 UNREACHABLE(); 5220 UNREACHABLE();
5221 } 5221 }
5222 5222
5223 5223
5224 void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { 5224 void HOptimizedGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
5225 ASSERT(!HasStackOverflow()); 5225 DCHECK(!HasStackOverflow());
5226 ASSERT(current_block() != NULL); 5226 DCHECK(current_block() != NULL);
5227 ASSERT(current_block()->HasPredecessor()); 5227 DCHECK(current_block()->HasPredecessor());
5228 Handle<SharedFunctionInfo> shared_info = expr->shared_info(); 5228 Handle<SharedFunctionInfo> shared_info = expr->shared_info();
5229 if (shared_info.is_null()) { 5229 if (shared_info.is_null()) {
5230 shared_info = 5230 shared_info =
5231 Compiler::BuildFunctionInfo(expr, current_info()->script(), top_info()); 5231 Compiler::BuildFunctionInfo(expr, current_info()->script(), top_info());
5232 } 5232 }
5233 // We also have a stack overflow if the recursive compilation did. 5233 // We also have a stack overflow if the recursive compilation did.
5234 if (HasStackOverflow()) return; 5234 if (HasStackOverflow()) return;
5235 HFunctionLiteral* instr = 5235 HFunctionLiteral* instr =
5236 New<HFunctionLiteral>(shared_info, expr->pretenure()); 5236 New<HFunctionLiteral>(shared_info, expr->pretenure());
5237 return ast_context()->ReturnInstruction(instr, expr->id()); 5237 return ast_context()->ReturnInstruction(instr, expr->id());
5238 } 5238 }
5239 5239
5240 5240
5241 void HOptimizedGraphBuilder::VisitNativeFunctionLiteral( 5241 void HOptimizedGraphBuilder::VisitNativeFunctionLiteral(
5242 NativeFunctionLiteral* expr) { 5242 NativeFunctionLiteral* expr) {
5243 ASSERT(!HasStackOverflow()); 5243 DCHECK(!HasStackOverflow());
5244 ASSERT(current_block() != NULL); 5244 DCHECK(current_block() != NULL);
5245 ASSERT(current_block()->HasPredecessor()); 5245 DCHECK(current_block()->HasPredecessor());
5246 return Bailout(kNativeFunctionLiteral); 5246 return Bailout(kNativeFunctionLiteral);
5247 } 5247 }
5248 5248
5249 5249
5250 void HOptimizedGraphBuilder::VisitConditional(Conditional* expr) { 5250 void HOptimizedGraphBuilder::VisitConditional(Conditional* expr) {
5251 ASSERT(!HasStackOverflow()); 5251 DCHECK(!HasStackOverflow());
5252 ASSERT(current_block() != NULL); 5252 DCHECK(current_block() != NULL);
5253 ASSERT(current_block()->HasPredecessor()); 5253 DCHECK(current_block()->HasPredecessor());
5254 HBasicBlock* cond_true = graph()->CreateBasicBlock(); 5254 HBasicBlock* cond_true = graph()->CreateBasicBlock();
5255 HBasicBlock* cond_false = graph()->CreateBasicBlock(); 5255 HBasicBlock* cond_false = graph()->CreateBasicBlock();
5256 CHECK_BAILOUT(VisitForControl(expr->condition(), cond_true, cond_false)); 5256 CHECK_BAILOUT(VisitForControl(expr->condition(), cond_true, cond_false));
5257 5257
5258 // Visit the true and false subexpressions in the same AST context as the 5258 // Visit the true and false subexpressions in the same AST context as the
5259 // whole expression. 5259 // whole expression.
5260 if (cond_true->HasPredecessor()) { 5260 if (cond_true->HasPredecessor()) {
5261 cond_true->SetJoinId(expr->ThenId()); 5261 cond_true->SetJoinId(expr->ThenId());
5262 set_current_block(cond_true); 5262 set_current_block(cond_true);
5263 CHECK_BAILOUT(Visit(expr->then_expression())); 5263 CHECK_BAILOUT(Visit(expr->then_expression()));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
5297 (access_type == STORE && lookup->IsReadOnly()) || 5297 (access_type == STORE && lookup->IsReadOnly()) ||
5298 lookup->holder() != *global) { 5298 lookup->holder() != *global) {
5299 return kUseGeneric; 5299 return kUseGeneric;
5300 } 5300 }
5301 5301
5302 return kUseCell; 5302 return kUseCell;
5303 } 5303 }
5304 5304
5305 5305
5306 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { 5306 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) {
5307 ASSERT(var->IsContextSlot()); 5307 DCHECK(var->IsContextSlot());
5308 HValue* context = environment()->context(); 5308 HValue* context = environment()->context();
5309 int length = scope()->ContextChainLength(var->scope()); 5309 int length = scope()->ContextChainLength(var->scope());
5310 while (length-- > 0) { 5310 while (length-- > 0) {
5311 context = Add<HLoadNamedField>( 5311 context = Add<HLoadNamedField>(
5312 context, static_cast<HValue*>(NULL), 5312 context, static_cast<HValue*>(NULL),
5313 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); 5313 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
5314 } 5314 }
5315 return context; 5315 return context;
5316 } 5316 }
5317 5317
5318 5318
5319 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 5319 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
5320 if (expr->is_this()) { 5320 if (expr->is_this()) {
5321 current_info()->set_this_has_uses(true); 5321 current_info()->set_this_has_uses(true);
5322 } 5322 }
5323 5323
5324 ASSERT(!HasStackOverflow()); 5324 DCHECK(!HasStackOverflow());
5325 ASSERT(current_block() != NULL); 5325 DCHECK(current_block() != NULL);
5326 ASSERT(current_block()->HasPredecessor()); 5326 DCHECK(current_block()->HasPredecessor());
5327 Variable* variable = expr->var(); 5327 Variable* variable = expr->var();
5328 switch (variable->location()) { 5328 switch (variable->location()) {
5329 case Variable::UNALLOCATED: { 5329 case Variable::UNALLOCATED: {
5330 if (IsLexicalVariableMode(variable->mode())) { 5330 if (IsLexicalVariableMode(variable->mode())) {
5331 // TODO(rossberg): should this be an ASSERT? 5331 // TODO(rossberg): should this be an DCHECK?
5332 return Bailout(kReferenceToGlobalLexicalVariable); 5332 return Bailout(kReferenceToGlobalLexicalVariable);
5333 } 5333 }
5334 // Handle known global constants like 'undefined' specially to avoid a 5334 // Handle known global constants like 'undefined' specially to avoid a
5335 // load from a global cell for them. 5335 // load from a global cell for them.
5336 Handle<Object> constant_value = 5336 Handle<Object> constant_value =
5337 isolate()->factory()->GlobalConstantFor(variable->name()); 5337 isolate()->factory()->GlobalConstantFor(variable->name());
5338 if (!constant_value.is_null()) { 5338 if (!constant_value.is_null()) {
5339 HConstant* instr = New<HConstant>(constant_value); 5339 HConstant* instr = New<HConstant>(constant_value);
5340 return ast_context()->ReturnInstruction(instr, expr->id()); 5340 return ast_context()->ReturnInstruction(instr, expr->id());
5341 } 5341 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
5381 expr->VariableFeedbackSlot()); 5381 expr->VariableFeedbackSlot());
5382 } 5382 }
5383 return ast_context()->ReturnInstruction(instr, expr->id()); 5383 return ast_context()->ReturnInstruction(instr, expr->id());
5384 } 5384 }
5385 } 5385 }
5386 5386
5387 case Variable::PARAMETER: 5387 case Variable::PARAMETER:
5388 case Variable::LOCAL: { 5388 case Variable::LOCAL: {
5389 HValue* value = LookupAndMakeLive(variable); 5389 HValue* value = LookupAndMakeLive(variable);
5390 if (value == graph()->GetConstantHole()) { 5390 if (value == graph()->GetConstantHole()) {
5391 ASSERT(IsDeclaredVariableMode(variable->mode()) && 5391 DCHECK(IsDeclaredVariableMode(variable->mode()) &&
5392 variable->mode() != VAR); 5392 variable->mode() != VAR);
5393 return Bailout(kReferenceToUninitializedVariable); 5393 return Bailout(kReferenceToUninitializedVariable);
5394 } 5394 }
5395 return ast_context()->ReturnValue(value); 5395 return ast_context()->ReturnValue(value);
5396 } 5396 }
5397 5397
5398 case Variable::CONTEXT: { 5398 case Variable::CONTEXT: {
5399 HValue* context = BuildContextChainWalk(variable); 5399 HValue* context = BuildContextChainWalk(variable);
5400 HLoadContextSlot::Mode mode; 5400 HLoadContextSlot::Mode mode;
5401 switch (variable->mode()) { 5401 switch (variable->mode()) {
(...skipping 13 matching lines...) Expand all
5415 return ast_context()->ReturnInstruction(instr, expr->id()); 5415 return ast_context()->ReturnInstruction(instr, expr->id());
5416 } 5416 }
5417 5417
5418 case Variable::LOOKUP: 5418 case Variable::LOOKUP:
5419 return Bailout(kReferenceToAVariableWhichRequiresDynamicLookup); 5419 return Bailout(kReferenceToAVariableWhichRequiresDynamicLookup);
5420 } 5420 }
5421 } 5421 }
5422 5422
5423 5423
5424 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) { 5424 void HOptimizedGraphBuilder::VisitLiteral(Literal* expr) {
5425 ASSERT(!HasStackOverflow()); 5425 DCHECK(!HasStackOverflow());
5426 ASSERT(current_block() != NULL); 5426 DCHECK(current_block() != NULL);
5427 ASSERT(current_block()->HasPredecessor()); 5427 DCHECK(current_block()->HasPredecessor());
5428 HConstant* instr = New<HConstant>(expr->value()); 5428 HConstant* instr = New<HConstant>(expr->value());
5429 return ast_context()->ReturnInstruction(instr, expr->id()); 5429 return ast_context()->ReturnInstruction(instr, expr->id());
5430 } 5430 }
5431 5431
5432 5432
5433 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { 5433 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
5434 ASSERT(!HasStackOverflow()); 5434 DCHECK(!HasStackOverflow());
5435 ASSERT(current_block() != NULL); 5435 DCHECK(current_block() != NULL);
5436 ASSERT(current_block()->HasPredecessor()); 5436 DCHECK(current_block()->HasPredecessor());
5437 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 5437 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
5438 Handle<FixedArray> literals(closure->literals()); 5438 Handle<FixedArray> literals(closure->literals());
5439 HRegExpLiteral* instr = New<HRegExpLiteral>(literals, 5439 HRegExpLiteral* instr = New<HRegExpLiteral>(literals,
5440 expr->pattern(), 5440 expr->pattern(),
5441 expr->flags(), 5441 expr->flags(),
5442 expr->literal_index()); 5442 expr->literal_index());
5443 return ast_context()->ReturnInstruction(instr, expr->id()); 5443 return ast_context()->ReturnInstruction(instr, expr->id());
5444 } 5444 }
5445 5445
5446 5446
(...skipping 11 matching lines...) Expand all
5458 // all limits to be considered for fast deep-copying and computes the total 5458 // all limits to be considered for fast deep-copying and computes the total
5459 // size of all objects that are part of the graph. 5459 // size of all objects that are part of the graph.
5460 static bool IsFastLiteral(Handle<JSObject> boilerplate, 5460 static bool IsFastLiteral(Handle<JSObject> boilerplate,
5461 int max_depth, 5461 int max_depth,
5462 int* max_properties) { 5462 int* max_properties) {
5463 if (boilerplate->map()->is_deprecated() && 5463 if (boilerplate->map()->is_deprecated() &&
5464 !JSObject::TryMigrateInstance(boilerplate)) { 5464 !JSObject::TryMigrateInstance(boilerplate)) {
5465 return false; 5465 return false;
5466 } 5466 }
5467 5467
5468 ASSERT(max_depth >= 0 && *max_properties >= 0); 5468 DCHECK(max_depth >= 0 && *max_properties >= 0);
5469 if (max_depth == 0) return false; 5469 if (max_depth == 0) return false;
5470 5470
5471 Isolate* isolate = boilerplate->GetIsolate(); 5471 Isolate* isolate = boilerplate->GetIsolate();
5472 Handle<FixedArrayBase> elements(boilerplate->elements()); 5472 Handle<FixedArrayBase> elements(boilerplate->elements());
5473 if (elements->length() > 0 && 5473 if (elements->length() > 0 &&
5474 elements->map() != isolate->heap()->fixed_cow_array_map()) { 5474 elements->map() != isolate->heap()->fixed_cow_array_map()) {
5475 if (boilerplate->HasFastObjectElements()) { 5475 if (boilerplate->HasFastObjectElements()) {
5476 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); 5476 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
5477 int length = elements->length(); 5477 int length = elements->length();
5478 for (int i = 0; i < length; i++) { 5478 for (int i = 0; i < length; i++) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
5513 return false; 5513 return false;
5514 } 5514 }
5515 } 5515 }
5516 } 5516 }
5517 } 5517 }
5518 return true; 5518 return true;
5519 } 5519 }
5520 5520
5521 5521
5522 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 5522 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
5523 ASSERT(!HasStackOverflow()); 5523 DCHECK(!HasStackOverflow());
5524 ASSERT(current_block() != NULL); 5524 DCHECK(current_block() != NULL);
5525 ASSERT(current_block()->HasPredecessor()); 5525 DCHECK(current_block()->HasPredecessor());
5526 expr->BuildConstantProperties(isolate()); 5526 expr->BuildConstantProperties(isolate());
5527 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 5527 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
5528 HInstruction* literal; 5528 HInstruction* literal;
5529 5529
5530 // Check whether to use fast or slow deep-copying for boilerplate. 5530 // Check whether to use fast or slow deep-copying for boilerplate.
5531 int max_properties = kMaxFastLiteralProperties; 5531 int max_properties = kMaxFastLiteralProperties;
5532 Handle<Object> literals_cell(closure->literals()->get(expr->literal_index()), 5532 Handle<Object> literals_cell(closure->literals()->get(expr->literal_index()),
5533 isolate()); 5533 isolate());
5534 Handle<AllocationSite> site; 5534 Handle<AllocationSite> site;
5535 Handle<JSObject> boilerplate; 5535 Handle<JSObject> boilerplate;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
5578 5578
5579 for (int i = 0; i < expr->properties()->length(); i++) { 5579 for (int i = 0; i < expr->properties()->length(); i++) {
5580 ObjectLiteral::Property* property = expr->properties()->at(i); 5580 ObjectLiteral::Property* property = expr->properties()->at(i);
5581 if (property->IsCompileTimeValue()) continue; 5581 if (property->IsCompileTimeValue()) continue;
5582 5582
5583 Literal* key = property->key(); 5583 Literal* key = property->key();
5584 Expression* value = property->value(); 5584 Expression* value = property->value();
5585 5585
5586 switch (property->kind()) { 5586 switch (property->kind()) {
5587 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 5587 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
5588 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 5588 DCHECK(!CompileTimeValue::IsCompileTimeValue(value));
5589 // Fall through. 5589 // Fall through.
5590 case ObjectLiteral::Property::COMPUTED: 5590 case ObjectLiteral::Property::COMPUTED:
5591 if (key->value()->IsInternalizedString()) { 5591 if (key->value()->IsInternalizedString()) {
5592 if (property->emit_store()) { 5592 if (property->emit_store()) {
5593 CHECK_ALIVE(VisitForValue(value)); 5593 CHECK_ALIVE(VisitForValue(value));
5594 HValue* value = Pop(); 5594 HValue* value = Pop();
5595 Handle<Map> map = property->GetReceiverType(); 5595 Handle<Map> map = property->GetReceiverType();
5596 Handle<String> name = property->key()->AsPropertyName(); 5596 Handle<String> name = property->key()->AsPropertyName();
5597 HInstruction* store; 5597 HInstruction* store;
5598 if (map.is_null()) { 5598 if (map.is_null()) {
5599 // If we don't know the monomorphic type, do a generic store. 5599 // If we don't know the monomorphic type, do a generic store.
5600 CHECK_ALIVE(store = BuildNamedGeneric( 5600 CHECK_ALIVE(store = BuildNamedGeneric(
5601 STORE, NULL, literal, name, value)); 5601 STORE, NULL, literal, name, value));
5602 } else { 5602 } else {
5603 PropertyAccessInfo info(this, STORE, ToType(map), name); 5603 PropertyAccessInfo info(this, STORE, ToType(map), name);
5604 if (info.CanAccessMonomorphic()) { 5604 if (info.CanAccessMonomorphic()) {
5605 HValue* checked_literal = Add<HCheckMaps>(literal, map); 5605 HValue* checked_literal = Add<HCheckMaps>(literal, map);
5606 ASSERT(!info.lookup()->IsPropertyCallbacks()); 5606 DCHECK(!info.lookup()->IsPropertyCallbacks());
5607 store = BuildMonomorphicAccess( 5607 store = BuildMonomorphicAccess(
5608 &info, literal, checked_literal, value, 5608 &info, literal, checked_literal, value,
5609 BailoutId::None(), BailoutId::None()); 5609 BailoutId::None(), BailoutId::None());
5610 } else { 5610 } else {
5611 CHECK_ALIVE(store = BuildNamedGeneric( 5611 CHECK_ALIVE(store = BuildNamedGeneric(
5612 STORE, NULL, literal, name, value)); 5612 STORE, NULL, literal, name, value));
5613 } 5613 }
5614 } 5614 }
5615 AddInstruction(store); 5615 AddInstruction(store);
5616 if (store->HasObservableSideEffects()) { 5616 if (store->HasObservableSideEffects()) {
(...skipping 21 matching lines...) Expand all
5638 // (e.g. because of code motion). 5638 // (e.g. because of code motion).
5639 HToFastProperties* result = Add<HToFastProperties>(Pop()); 5639 HToFastProperties* result = Add<HToFastProperties>(Pop());
5640 return ast_context()->ReturnValue(result); 5640 return ast_context()->ReturnValue(result);
5641 } else { 5641 } else {
5642 return ast_context()->ReturnValue(Pop()); 5642 return ast_context()->ReturnValue(Pop());
5643 } 5643 }
5644 } 5644 }
5645 5645
5646 5646
5647 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 5647 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
5648 ASSERT(!HasStackOverflow()); 5648 DCHECK(!HasStackOverflow());
5649 ASSERT(current_block() != NULL); 5649 DCHECK(current_block() != NULL);
5650 ASSERT(current_block()->HasPredecessor()); 5650 DCHECK(current_block()->HasPredecessor());
5651 expr->BuildConstantElements(isolate()); 5651 expr->BuildConstantElements(isolate());
5652 ZoneList<Expression*>* subexprs = expr->values(); 5652 ZoneList<Expression*>* subexprs = expr->values();
5653 int length = subexprs->length(); 5653 int length = subexprs->length();
5654 HInstruction* literal; 5654 HInstruction* literal;
5655 5655
5656 Handle<AllocationSite> site; 5656 Handle<AllocationSite> site;
5657 Handle<FixedArray> literals(environment()->closure()->literals(), isolate()); 5657 Handle<FixedArray> literals(environment()->closure()->literals(), isolate());
5658 bool uninitialized = false; 5658 bool uninitialized = false;
5659 Handle<Object> literals_cell(literals->get(expr->literal_index()), 5659 Handle<Object> literals_cell(literals->get(expr->literal_index()),
5660 isolate()); 5660 isolate());
(...skipping 14 matching lines...) Expand all
5675 return Bailout(kArrayBoilerplateCreationFailed); 5675 return Bailout(kArrayBoilerplateCreationFailed);
5676 } 5676 }
5677 creation_context.ExitScope(site, boilerplate_object); 5677 creation_context.ExitScope(site, boilerplate_object);
5678 literals->set(expr->literal_index(), *site); 5678 literals->set(expr->literal_index(), *site);
5679 5679
5680 if (boilerplate_object->elements()->map() == 5680 if (boilerplate_object->elements()->map() ==
5681 isolate()->heap()->fixed_cow_array_map()) { 5681 isolate()->heap()->fixed_cow_array_map()) {
5682 isolate()->counters()->cow_arrays_created_runtime()->Increment(); 5682 isolate()->counters()->cow_arrays_created_runtime()->Increment();
5683 } 5683 }
5684 } else { 5684 } else {
5685 ASSERT(literals_cell->IsAllocationSite()); 5685 DCHECK(literals_cell->IsAllocationSite());
5686 site = Handle<AllocationSite>::cast(literals_cell); 5686 site = Handle<AllocationSite>::cast(literals_cell);
5687 boilerplate_object = Handle<JSObject>( 5687 boilerplate_object = Handle<JSObject>(
5688 JSObject::cast(site->transition_info()), isolate()); 5688 JSObject::cast(site->transition_info()), isolate());
5689 } 5689 }
5690 5690
5691 ASSERT(!boilerplate_object.is_null()); 5691 DCHECK(!boilerplate_object.is_null());
5692 ASSERT(site->SitePointsToLiteral()); 5692 DCHECK(site->SitePointsToLiteral());
5693 5693
5694 ElementsKind boilerplate_elements_kind = 5694 ElementsKind boilerplate_elements_kind =
5695 boilerplate_object->GetElementsKind(); 5695 boilerplate_object->GetElementsKind();
5696 5696
5697 // Check whether to use fast or slow deep-copying for boilerplate. 5697 // Check whether to use fast or slow deep-copying for boilerplate.
5698 int max_properties = kMaxFastLiteralProperties; 5698 int max_properties = kMaxFastLiteralProperties;
5699 if (IsFastLiteral(boilerplate_object, 5699 if (IsFastLiteral(boilerplate_object,
5700 kMaxFastLiteralDepth, 5700 kMaxFastLiteralDepth,
5701 &max_properties)) { 5701 &max_properties)) {
5702 AllocationSiteUsageContext usage_context(isolate(), site, false); 5702 AllocationSiteUsageContext usage_context(isolate(), site, false);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
5794 info->lookup()->IsCacheable() && 5794 info->lookup()->IsCacheable() &&
5795 info->lookup()->IsReadOnly() && info->lookup()->IsDontDelete()) { 5795 info->lookup()->IsReadOnly() && info->lookup()->IsDontDelete()) {
5796 Handle<Object> object( 5796 Handle<Object> object(
5797 HConstant::cast(checked_object->ActualValue())->handle(isolate())); 5797 HConstant::cast(checked_object->ActualValue())->handle(isolate()));
5798 5798
5799 if (object->IsJSObject()) { 5799 if (object->IsJSObject()) {
5800 LookupResult lookup(isolate()); 5800 LookupResult lookup(isolate());
5801 Handle<JSObject>::cast(object)->Lookup(info->name(), &lookup); 5801 Handle<JSObject>::cast(object)->Lookup(info->name(), &lookup);
5802 Handle<Object> value(lookup.GetLazyValue(), isolate()); 5802 Handle<Object> value(lookup.GetLazyValue(), isolate());
5803 5803
5804 ASSERT(!value->IsTheHole()); 5804 DCHECK(!value->IsTheHole());
5805 return New<HConstant>(value); 5805 return New<HConstant>(value);
5806 } 5806 }
5807 } 5807 }
5808 5808
5809 HObjectAccess access = info->access(); 5809 HObjectAccess access = info->access();
5810 if (access.representation().IsDouble()) { 5810 if (access.representation().IsDouble()) {
5811 // Load the heap number. 5811 // Load the heap number.
5812 checked_object = Add<HLoadNamedField>( 5812 checked_object = Add<HLoadNamedField>(
5813 checked_object, static_cast<HValue*>(NULL), 5813 checked_object, static_cast<HValue*>(NULL),
5814 access.WithRepresentation(Representation::Tagged())); 5814 access.WithRepresentation(Representation::Tagged()));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
5866 instr = New<HStoreNamedField>(heap_number, 5866 instr = New<HStoreNamedField>(heap_number,
5867 HObjectAccess::ForHeapNumberValue(), 5867 HObjectAccess::ForHeapNumberValue(),
5868 value, STORE_TO_INITIALIZED_ENTRY); 5868 value, STORE_TO_INITIALIZED_ENTRY);
5869 } 5869 }
5870 } else { 5870 } else {
5871 if (field_access.representation().IsHeapObject()) { 5871 if (field_access.representation().IsHeapObject()) {
5872 BuildCheckHeapObject(value); 5872 BuildCheckHeapObject(value);
5873 } 5873 }
5874 5874
5875 if (!info->field_maps()->is_empty()) { 5875 if (!info->field_maps()->is_empty()) {
5876 ASSERT(field_access.representation().IsHeapObject()); 5876 DCHECK(field_access.representation().IsHeapObject());
5877 value = Add<HCheckMaps>(value, info->field_maps()); 5877 value = Add<HCheckMaps>(value, info->field_maps());
5878 } 5878 }
5879 5879
5880 // This is a normal store. 5880 // This is a normal store.
5881 instr = New<HStoreNamedField>( 5881 instr = New<HStoreNamedField>(
5882 checked_object->ActualValue(), field_access, value, 5882 checked_object->ActualValue(), field_access, value,
5883 transition_to_field ? INITIALIZING_STORE : STORE_TO_INITIALIZED_ENTRY); 5883 transition_to_field ? INITIALIZING_STORE : STORE_TO_INITIALIZED_ENTRY);
5884 } 5884 }
5885 5885
5886 if (transition_to_field) { 5886 if (transition_to_field) {
5887 Handle<Map> transition(info->transition()); 5887 Handle<Map> transition(info->transition());
5888 ASSERT(!transition->is_deprecated()); 5888 DCHECK(!transition->is_deprecated());
5889 instr->SetTransition(Add<HConstant>(transition)); 5889 instr->SetTransition(Add<HConstant>(transition));
5890 } 5890 }
5891 return instr; 5891 return instr;
5892 } 5892 }
5893 5893
5894 5894
5895 bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible( 5895 bool HOptimizedGraphBuilder::PropertyAccessInfo::IsCompatible(
5896 PropertyAccessInfo* info) { 5896 PropertyAccessInfo* info) {
5897 if (!CanInlinePropertyAccess(type_)) return false; 5897 if (!CanInlinePropertyAccess(type_)) return false;
5898 5898
(...skipping 23 matching lines...) Expand all
5922 5922
5923 if (lookup_.IsPropertyCallbacks()) { 5923 if (lookup_.IsPropertyCallbacks()) {
5924 return accessor_.is_identical_to(info->accessor_) && 5924 return accessor_.is_identical_to(info->accessor_) &&
5925 api_holder_.is_identical_to(info->api_holder_); 5925 api_holder_.is_identical_to(info->api_holder_);
5926 } 5926 }
5927 5927
5928 if (lookup_.IsConstant()) { 5928 if (lookup_.IsConstant()) {
5929 return constant_.is_identical_to(info->constant_); 5929 return constant_.is_identical_to(info->constant_);
5930 } 5930 }
5931 5931
5932 ASSERT(lookup_.IsField()); 5932 DCHECK(lookup_.IsField());
5933 if (!info->lookup_.IsField()) return false; 5933 if (!info->lookup_.IsField()) return false;
5934 5934
5935 Representation r = access_.representation(); 5935 Representation r = access_.representation();
5936 if (IsLoad()) { 5936 if (IsLoad()) {
5937 if (!info->access_.representation().IsCompatibleForLoad(r)) return false; 5937 if (!info->access_.representation().IsCompatibleForLoad(r)) return false;
5938 } else { 5938 } else {
5939 if (!info->access_.representation().IsCompatibleForStore(r)) return false; 5939 if (!info->access_.representation().IsCompatibleForStore(r)) return false;
5940 } 5940 }
5941 if (info->access_.offset() != access_.offset()) return false; 5941 if (info->access_.offset() != access_.offset()) return false;
5942 if (info->access_.IsInobject() != access_.IsInobject()) return false; 5942 if (info->access_.IsInobject() != access_.IsInobject()) return false;
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
6015 // Clear any previously collected field maps/type. 6015 // Clear any previously collected field maps/type.
6016 field_maps_.Clear(); 6016 field_maps_.Clear();
6017 field_type_ = HType::Tagged(); 6017 field_type_ = HType::Tagged();
6018 6018
6019 // Figure out the field type from the accessor map. 6019 // Figure out the field type from the accessor map.
6020 Handle<HeapType> field_type(lookup_.GetFieldTypeFromMap(*map), isolate()); 6020 Handle<HeapType> field_type(lookup_.GetFieldTypeFromMap(*map), isolate());
6021 6021
6022 // Collect the (stable) maps from the field type. 6022 // Collect the (stable) maps from the field type.
6023 int num_field_maps = field_type->NumClasses(); 6023 int num_field_maps = field_type->NumClasses();
6024 if (num_field_maps == 0) return; 6024 if (num_field_maps == 0) return;
6025 ASSERT(access_.representation().IsHeapObject()); 6025 DCHECK(access_.representation().IsHeapObject());
6026 field_maps_.Reserve(num_field_maps, zone()); 6026 field_maps_.Reserve(num_field_maps, zone());
6027 HeapType::Iterator<Map> it = field_type->Classes(); 6027 HeapType::Iterator<Map> it = field_type->Classes();
6028 while (!it.Done()) { 6028 while (!it.Done()) {
6029 Handle<Map> field_map = it.Current(); 6029 Handle<Map> field_map = it.Current();
6030 if (!field_map->is_stable()) { 6030 if (!field_map->is_stable()) {
6031 field_maps_.Clear(); 6031 field_maps_.Clear();
6032 return; 6032 return;
6033 } 6033 }
6034 field_maps_.Add(field_map, zone()); 6034 field_maps_.Add(field_map, zone());
6035 it.Advance(); 6035 it.Advance();
6036 } 6036 }
6037 field_maps_.Sort(); 6037 field_maps_.Sort();
6038 ASSERT_EQ(num_field_maps, field_maps_.length()); 6038 DCHECK_EQ(num_field_maps, field_maps_.length());
6039 6039
6040 // Determine field HType from field HeapType. 6040 // Determine field HType from field HeapType.
6041 field_type_ = HType::FromType<HeapType>(field_type); 6041 field_type_ = HType::FromType<HeapType>(field_type);
6042 ASSERT(field_type_.IsHeapObject()); 6042 DCHECK(field_type_.IsHeapObject());
6043 6043
6044 // Add dependency on the map that introduced the field. 6044 // Add dependency on the map that introduced the field.
6045 Map::AddDependentCompilationInfo( 6045 Map::AddDependentCompilationInfo(
6046 handle(lookup_.GetFieldOwnerFromMap(*map), isolate()), 6046 handle(lookup_.GetFieldOwnerFromMap(*map), isolate()),
6047 DependentCode::kFieldTypeGroup, top_info()); 6047 DependentCode::kFieldTypeGroup, top_info());
6048 } 6048 }
6049 6049
6050 6050
6051 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { 6051 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() {
6052 Handle<Map> map = this->map(); 6052 Handle<Map> map = this->map();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
6095 // Load field map for heap objects. 6095 // Load field map for heap objects.
6096 LoadFieldMaps(transition()); 6096 LoadFieldMaps(transition());
6097 return true; 6097 return true;
6098 } 6098 }
6099 return false; 6099 return false;
6100 } 6100 }
6101 6101
6102 6102
6103 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic( 6103 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic(
6104 SmallMapList* types) { 6104 SmallMapList* types) {
6105 ASSERT(type_->Is(ToType(types->first()))); 6105 DCHECK(type_->Is(ToType(types->first())));
6106 if (!CanAccessMonomorphic()) return false; 6106 if (!CanAccessMonomorphic()) return false;
6107 STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); 6107 STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism);
6108 if (types->length() > kMaxLoadPolymorphism) return false; 6108 if (types->length() > kMaxLoadPolymorphism) return false;
6109 6109
6110 HObjectAccess access = HObjectAccess::ForMap(); // bogus default 6110 HObjectAccess access = HObjectAccess::ForMap(); // bogus default
6111 if (GetJSObjectFieldAccess(&access)) { 6111 if (GetJSObjectFieldAccess(&access)) {
6112 for (int i = 1; i < types->length(); ++i) { 6112 for (int i = 1; i < types->length(); ++i) {
6113 PropertyAccessInfo test_info( 6113 PropertyAccessInfo test_info(
6114 builder_, access_type_, ToType(types->at(i)), name_); 6114 builder_, access_type_, ToType(types->at(i)), name_);
6115 HObjectAccess test_access = HObjectAccess::ForMap(); // bogus default 6115 HObjectAccess test_access = HObjectAccess::ForMap(); // bogus default
6116 if (!test_info.GetJSObjectFieldAccess(&test_access)) return false; 6116 if (!test_info.GetJSObjectFieldAccess(&test_access)) return false;
6117 if (!access.Equals(test_access)) return false; 6117 if (!access.Equals(test_access)) return false;
6118 } 6118 }
6119 return true; 6119 return true;
6120 } 6120 }
6121 6121
6122 // Currently only handle Type::Number as a polymorphic case. 6122 // Currently only handle Type::Number as a polymorphic case.
6123 // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber 6123 // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber
6124 // instruction. 6124 // instruction.
6125 if (type_->Is(Type::Number())) return false; 6125 if (type_->Is(Type::Number())) return false;
6126 6126
6127 // Multiple maps cannot transition to the same target map. 6127 // Multiple maps cannot transition to the same target map.
6128 ASSERT(!IsLoad() || !lookup_.IsTransition()); 6128 DCHECK(!IsLoad() || !lookup_.IsTransition());
6129 if (lookup_.IsTransition() && types->length() > 1) return false; 6129 if (lookup_.IsTransition() && types->length() > 1) return false;
6130 6130
6131 for (int i = 1; i < types->length(); ++i) { 6131 for (int i = 1; i < types->length(); ++i) {
6132 PropertyAccessInfo test_info( 6132 PropertyAccessInfo test_info(
6133 builder_, access_type_, ToType(types->at(i)), name_); 6133 builder_, access_type_, ToType(types->at(i)), name_);
6134 if (!test_info.IsCompatible(this)) return false; 6134 if (!test_info.IsCompatible(this)) return false;
6135 } 6135 }
6136 6136
6137 return true; 6137 return true;
6138 } 6138 }
(...skipping 18 matching lines...) Expand all
6157 PropertyAccessInfo* info, 6157 PropertyAccessInfo* info,
6158 HValue* object, 6158 HValue* object,
6159 HValue* checked_object, 6159 HValue* checked_object,
6160 HValue* value, 6160 HValue* value,
6161 BailoutId ast_id, 6161 BailoutId ast_id,
6162 BailoutId return_id, 6162 BailoutId return_id,
6163 bool can_inline_accessor) { 6163 bool can_inline_accessor) {
6164 6164
6165 HObjectAccess access = HObjectAccess::ForMap(); // bogus default 6165 HObjectAccess access = HObjectAccess::ForMap(); // bogus default
6166 if (info->GetJSObjectFieldAccess(&access)) { 6166 if (info->GetJSObjectFieldAccess(&access)) {
6167 ASSERT(info->IsLoad()); 6167 DCHECK(info->IsLoad());
6168 return New<HLoadNamedField>(object, checked_object, access); 6168 return New<HLoadNamedField>(object, checked_object, access);
6169 } 6169 }
6170 6170
6171 if (info->name().is_identical_to(isolate()->factory()->prototype_string()) && 6171 if (info->name().is_identical_to(isolate()->factory()->prototype_string()) &&
6172 info->map()->function_with_prototype()) { 6172 info->map()->function_with_prototype()) {
6173 ASSERT(!info->map()->has_non_instance_prototype()); 6173 DCHECK(!info->map()->has_non_instance_prototype());
6174 return New<HLoadFunctionPrototype>(checked_object); 6174 return New<HLoadFunctionPrototype>(checked_object);
6175 } 6175 }
6176 6176
6177 HValue* checked_holder = checked_object; 6177 HValue* checked_holder = checked_object;
6178 if (info->has_holder()) { 6178 if (info->has_holder()) {
6179 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype())); 6179 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype()));
6180 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); 6180 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder());
6181 } 6181 }
6182 6182
6183 if (!info->lookup()->IsFound()) { 6183 if (!info->lookup()->IsFound()) {
6184 ASSERT(info->IsLoad()); 6184 DCHECK(info->IsLoad());
6185 return graph()->GetConstantUndefined(); 6185 return graph()->GetConstantUndefined();
6186 } 6186 }
6187 6187
6188 if (info->lookup()->IsField()) { 6188 if (info->lookup()->IsField()) {
6189 if (info->IsLoad()) { 6189 if (info->IsLoad()) {
6190 return BuildLoadNamedField(info, checked_holder); 6190 return BuildLoadNamedField(info, checked_holder);
6191 } else { 6191 } else {
6192 return BuildStoreNamedField(info, checked_object, value); 6192 return BuildStoreNamedField(info, checked_object, value);
6193 } 6193 }
6194 } 6194 }
6195 6195
6196 if (info->lookup()->IsTransition()) { 6196 if (info->lookup()->IsTransition()) {
6197 ASSERT(!info->IsLoad()); 6197 DCHECK(!info->IsLoad());
6198 return BuildStoreNamedField(info, checked_object, value); 6198 return BuildStoreNamedField(info, checked_object, value);
6199 } 6199 }
6200 6200
6201 if (info->lookup()->IsPropertyCallbacks()) { 6201 if (info->lookup()->IsPropertyCallbacks()) {
6202 Push(checked_object); 6202 Push(checked_object);
6203 int argument_count = 1; 6203 int argument_count = 1;
6204 if (!info->IsLoad()) { 6204 if (!info->IsLoad()) {
6205 argument_count = 2; 6205 argument_count = 2;
6206 Push(value); 6206 Push(value);
6207 } 6207 }
6208 6208
6209 if (NeedsWrappingFor(info->type(), info->accessor())) { 6209 if (NeedsWrappingFor(info->type(), info->accessor())) {
6210 HValue* function = Add<HConstant>(info->accessor()); 6210 HValue* function = Add<HConstant>(info->accessor());
6211 PushArgumentsFromEnvironment(argument_count); 6211 PushArgumentsFromEnvironment(argument_count);
6212 return New<HCallFunction>(function, argument_count, WRAP_AND_CALL); 6212 return New<HCallFunction>(function, argument_count, WRAP_AND_CALL);
6213 } else if (FLAG_inline_accessors && can_inline_accessor) { 6213 } else if (FLAG_inline_accessors && can_inline_accessor) {
6214 bool success = info->IsLoad() 6214 bool success = info->IsLoad()
6215 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) 6215 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id)
6216 : TryInlineSetter( 6216 : TryInlineSetter(
6217 info->accessor(), info->map(), ast_id, return_id, value); 6217 info->accessor(), info->map(), ast_id, return_id, value);
6218 if (success || HasStackOverflow()) return NULL; 6218 if (success || HasStackOverflow()) return NULL;
6219 } 6219 }
6220 6220
6221 PushArgumentsFromEnvironment(argument_count); 6221 PushArgumentsFromEnvironment(argument_count);
6222 return BuildCallConstantFunction(info->accessor(), argument_count); 6222 return BuildCallConstantFunction(info->accessor(), argument_count);
6223 } 6223 }
6224 6224
6225 ASSERT(info->lookup()->IsConstant()); 6225 DCHECK(info->lookup()->IsConstant());
6226 if (info->IsLoad()) { 6226 if (info->IsLoad()) {
6227 return New<HConstant>(info->constant()); 6227 return New<HConstant>(info->constant());
6228 } else { 6228 } else {
6229 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); 6229 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant()));
6230 } 6230 }
6231 } 6231 }
6232 6232
6233 6233
6234 void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( 6234 void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess(
6235 PropertyAccessType access_type, 6235 PropertyAccessType access_type,
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
6354 6354
6355 if (join != NULL) { 6355 if (join != NULL) {
6356 Goto(join); 6356 Goto(join);
6357 } else { 6357 } else {
6358 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6358 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6359 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6359 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6360 return; 6360 return;
6361 } 6361 }
6362 } 6362 }
6363 6363
6364 ASSERT(join != NULL); 6364 DCHECK(join != NULL);
6365 if (join->HasPredecessor()) { 6365 if (join->HasPredecessor()) {
6366 join->SetJoinId(ast_id); 6366 join->SetJoinId(ast_id);
6367 set_current_block(join); 6367 set_current_block(join);
6368 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6368 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6369 } else { 6369 } else {
6370 set_current_block(NULL); 6370 set_current_block(NULL);
6371 } 6371 }
6372 } 6372 }
6373 6373
6374 6374
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
6415 Add<HSimulate>(return_id, REMOVABLE_SIMULATE); 6415 Add<HSimulate>(return_id, REMOVABLE_SIMULATE);
6416 return ast_context()->ReturnValue(Pop()); 6416 return ast_context()->ReturnValue(Pop());
6417 } 6417 }
6418 6418
6419 // Named store. 6419 // Named store.
6420 HValue* value = Pop(); 6420 HValue* value = Pop();
6421 HValue* object = Pop(); 6421 HValue* object = Pop();
6422 6422
6423 Literal* key = prop->key()->AsLiteral(); 6423 Literal* key = prop->key()->AsLiteral();
6424 Handle<String> name = Handle<String>::cast(key->value()); 6424 Handle<String> name = Handle<String>::cast(key->value());
6425 ASSERT(!name.is_null()); 6425 DCHECK(!name.is_null());
6426 6426
6427 HInstruction* instr = BuildNamedAccess(STORE, ast_id, return_id, expr, 6427 HInstruction* instr = BuildNamedAccess(STORE, ast_id, return_id, expr,
6428 object, name, value, is_uninitialized); 6428 object, name, value, is_uninitialized);
6429 if (instr == NULL) return; 6429 if (instr == NULL) return;
6430 6430
6431 if (!ast_context()->IsEffect()) Push(value); 6431 if (!ast_context()->IsEffect()) Push(value);
6432 AddInstruction(instr); 6432 AddInstruction(instr);
6433 if (instr->HasObservableSideEffects()) { 6433 if (instr->HasObservableSideEffects()) {
6434 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6434 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6435 } 6435 }
6436 if (!ast_context()->IsEffect()) Drop(1); 6436 if (!ast_context()->IsEffect()) Drop(1);
6437 return ast_context()->ReturnValue(value); 6437 return ast_context()->ReturnValue(value);
6438 } 6438 }
6439 6439
6440 6440
6441 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 6441 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
6442 Property* prop = expr->target()->AsProperty(); 6442 Property* prop = expr->target()->AsProperty();
6443 ASSERT(prop != NULL); 6443 DCHECK(prop != NULL);
6444 CHECK_ALIVE(VisitForValue(prop->obj())); 6444 CHECK_ALIVE(VisitForValue(prop->obj()));
6445 if (!prop->key()->IsPropertyName()) { 6445 if (!prop->key()->IsPropertyName()) {
6446 CHECK_ALIVE(VisitForValue(prop->key())); 6446 CHECK_ALIVE(VisitForValue(prop->key()));
6447 } 6447 }
6448 CHECK_ALIVE(VisitForValue(expr->value())); 6448 CHECK_ALIVE(VisitForValue(expr->value()));
6449 BuildStore(expr, prop, expr->id(), 6449 BuildStore(expr, prop, expr->id(),
6450 expr->AssignmentId(), expr->IsUninitialized()); 6450 expr->AssignmentId(), expr->IsUninitialized());
6451 } 6451 }
6452 6452
6453 6453
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
6492 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6492 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6493 } 6493 }
6494 } else { 6494 } else {
6495 HValue* global_object = Add<HLoadNamedField>( 6495 HValue* global_object = Add<HLoadNamedField>(
6496 context(), static_cast<HValue*>(NULL), 6496 context(), static_cast<HValue*>(NULL),
6497 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 6497 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
6498 HStoreNamedGeneric* instr = 6498 HStoreNamedGeneric* instr =
6499 Add<HStoreNamedGeneric>(global_object, var->name(), 6499 Add<HStoreNamedGeneric>(global_object, var->name(),
6500 value, function_strict_mode()); 6500 value, function_strict_mode());
6501 USE(instr); 6501 USE(instr);
6502 ASSERT(instr->HasObservableSideEffects()); 6502 DCHECK(instr->HasObservableSideEffects());
6503 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 6503 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
6504 } 6504 }
6505 } 6505 }
6506 6506
6507 6507
6508 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 6508 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
6509 Expression* target = expr->target(); 6509 Expression* target = expr->target();
6510 VariableProxy* proxy = target->AsVariableProxy(); 6510 VariableProxy* proxy = target->AsVariableProxy();
6511 Property* prop = target->AsProperty(); 6511 Property* prop = target->AsProperty();
6512 ASSERT(proxy == NULL || prop == NULL); 6512 DCHECK(proxy == NULL || prop == NULL);
6513 6513
6514 // We have a second position recorded in the FullCodeGenerator to have 6514 // We have a second position recorded in the FullCodeGenerator to have
6515 // type feedback for the binary operation. 6515 // type feedback for the binary operation.
6516 BinaryOperation* operation = expr->binary_operation(); 6516 BinaryOperation* operation = expr->binary_operation();
6517 6517
6518 if (proxy != NULL) { 6518 if (proxy != NULL) {
6519 Variable* var = proxy->var(); 6519 Variable* var = proxy->var();
6520 if (var->mode() == LET) { 6520 if (var->mode() == LET) {
6521 return Bailout(kUnsupportedLetCompoundAssignment); 6521 return Bailout(kUnsupportedLetCompoundAssignment);
6522 } 6522 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
6603 6603
6604 BuildStore(expr, prop, expr->id(), 6604 BuildStore(expr, prop, expr->id(),
6605 expr->AssignmentId(), expr->IsUninitialized()); 6605 expr->AssignmentId(), expr->IsUninitialized());
6606 } else { 6606 } else {
6607 return Bailout(kInvalidLhsInCompoundAssignment); 6607 return Bailout(kInvalidLhsInCompoundAssignment);
6608 } 6608 }
6609 } 6609 }
6610 6610
6611 6611
6612 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) { 6612 void HOptimizedGraphBuilder::VisitAssignment(Assignment* expr) {
6613 ASSERT(!HasStackOverflow()); 6613 DCHECK(!HasStackOverflow());
6614 ASSERT(current_block() != NULL); 6614 DCHECK(current_block() != NULL);
6615 ASSERT(current_block()->HasPredecessor()); 6615 DCHECK(current_block()->HasPredecessor());
6616 VariableProxy* proxy = expr->target()->AsVariableProxy(); 6616 VariableProxy* proxy = expr->target()->AsVariableProxy();
6617 Property* prop = expr->target()->AsProperty(); 6617 Property* prop = expr->target()->AsProperty();
6618 ASSERT(proxy == NULL || prop == NULL); 6618 DCHECK(proxy == NULL || prop == NULL);
6619 6619
6620 if (expr->is_compound()) { 6620 if (expr->is_compound()) {
6621 HandleCompoundAssignment(expr); 6621 HandleCompoundAssignment(expr);
6622 return; 6622 return;
6623 } 6623 }
6624 6624
6625 if (prop != NULL) { 6625 if (prop != NULL) {
6626 HandlePropertyAssignment(expr); 6626 HandlePropertyAssignment(expr);
6627 } else if (proxy != NULL) { 6627 } else if (proxy != NULL) {
6628 Variable* var = proxy->var(); 6628 Variable* var = proxy->var();
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
6704 case CONST_LEGACY: 6704 case CONST_LEGACY:
6705 return ast_context()->ReturnValue(Pop()); 6705 return ast_context()->ReturnValue(Pop());
6706 default: 6706 default:
6707 mode = HStoreContextSlot::kNoCheck; 6707 mode = HStoreContextSlot::kNoCheck;
6708 } 6708 }
6709 } else if (expr->op() == Token::INIT_VAR || 6709 } else if (expr->op() == Token::INIT_VAR ||
6710 expr->op() == Token::INIT_LET || 6710 expr->op() == Token::INIT_LET ||
6711 expr->op() == Token::INIT_CONST) { 6711 expr->op() == Token::INIT_CONST) {
6712 mode = HStoreContextSlot::kNoCheck; 6712 mode = HStoreContextSlot::kNoCheck;
6713 } else { 6713 } else {
6714 ASSERT(expr->op() == Token::INIT_CONST_LEGACY); 6714 DCHECK(expr->op() == Token::INIT_CONST_LEGACY);
6715 6715
6716 mode = HStoreContextSlot::kCheckIgnoreAssignment; 6716 mode = HStoreContextSlot::kCheckIgnoreAssignment;
6717 } 6717 }
6718 6718
6719 HValue* context = BuildContextChainWalk(var); 6719 HValue* context = BuildContextChainWalk(var);
6720 HStoreContextSlot* instr = Add<HStoreContextSlot>( 6720 HStoreContextSlot* instr = Add<HStoreContextSlot>(
6721 context, var->index(), mode, Top()); 6721 context, var->index(), mode, Top());
6722 if (instr->HasObservableSideEffects()) { 6722 if (instr->HasObservableSideEffects()) {
6723 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 6723 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
6724 } 6724 }
6725 return ast_context()->ReturnValue(Pop()); 6725 return ast_context()->ReturnValue(Pop());
6726 } 6726 }
6727 6727
6728 case Variable::LOOKUP: 6728 case Variable::LOOKUP:
6729 return Bailout(kAssignmentToLOOKUPVariable); 6729 return Bailout(kAssignmentToLOOKUPVariable);
6730 } 6730 }
6731 } else { 6731 } else {
6732 return Bailout(kInvalidLeftHandSideInAssignment); 6732 return Bailout(kInvalidLeftHandSideInAssignment);
6733 } 6733 }
6734 } 6734 }
6735 6735
6736 6736
6737 void HOptimizedGraphBuilder::VisitYield(Yield* expr) { 6737 void HOptimizedGraphBuilder::VisitYield(Yield* expr) {
6738 // Generators are not optimized, so we should never get here. 6738 // Generators are not optimized, so we should never get here.
6739 UNREACHABLE(); 6739 UNREACHABLE();
6740 } 6740 }
6741 6741
6742 6742
6743 void HOptimizedGraphBuilder::VisitThrow(Throw* expr) { 6743 void HOptimizedGraphBuilder::VisitThrow(Throw* expr) {
6744 ASSERT(!HasStackOverflow()); 6744 DCHECK(!HasStackOverflow());
6745 ASSERT(current_block() != NULL); 6745 DCHECK(current_block() != NULL);
6746 ASSERT(current_block()->HasPredecessor()); 6746 DCHECK(current_block()->HasPredecessor());
6747 // We don't optimize functions with invalid left-hand sides in 6747 // We don't optimize functions with invalid left-hand sides in
6748 // assignments, count operations, or for-in. Consequently throw can 6748 // assignments, count operations, or for-in. Consequently throw can
6749 // currently only occur in an effect context. 6749 // currently only occur in an effect context.
6750 ASSERT(ast_context()->IsEffect()); 6750 DCHECK(ast_context()->IsEffect());
6751 CHECK_ALIVE(VisitForValue(expr->exception())); 6751 CHECK_ALIVE(VisitForValue(expr->exception()));
6752 6752
6753 HValue* value = environment()->Pop(); 6753 HValue* value = environment()->Pop();
6754 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 6754 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
6755 Add<HPushArguments>(value); 6755 Add<HPushArguments>(value);
6756 Add<HCallRuntime>(isolate()->factory()->empty_string(), 6756 Add<HCallRuntime>(isolate()->factory()->empty_string(),
6757 Runtime::FunctionForId(Runtime::kThrow), 1); 6757 Runtime::FunctionForId(Runtime::kThrow), 1);
6758 Add<HSimulate>(expr->id()); 6758 Add<HSimulate>(expr->id());
6759 6759
6760 // If the throw definitely exits the function, we can finish with a dummy 6760 // If the throw definitely exits the function, we can finish with a dummy
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
6874 if (access_type == STORE && map->prototype()->IsJSObject()) { 6874 if (access_type == STORE && map->prototype()->IsJSObject()) {
6875 // monomorphic stores need a prototype chain check because shape 6875 // monomorphic stores need a prototype chain check because shape
6876 // changes could allow callbacks on elements in the chain that 6876 // changes could allow callbacks on elements in the chain that
6877 // aren't compatible with monomorphic keyed stores. 6877 // aren't compatible with monomorphic keyed stores.
6878 PrototypeIterator iter(map); 6878 PrototypeIterator iter(map);
6879 JSObject* holder = NULL; 6879 JSObject* holder = NULL;
6880 while (!iter.IsAtEnd()) { 6880 while (!iter.IsAtEnd()) {
6881 holder = JSObject::cast(*PrototypeIterator::GetCurrent(iter)); 6881 holder = JSObject::cast(*PrototypeIterator::GetCurrent(iter));
6882 iter.Advance(); 6882 iter.Advance();
6883 } 6883 }
6884 ASSERT(holder && holder->IsJSObject()); 6884 DCHECK(holder && holder->IsJSObject());
6885 6885
6886 BuildCheckPrototypeMaps(handle(JSObject::cast(map->prototype())), 6886 BuildCheckPrototypeMaps(handle(JSObject::cast(map->prototype())),
6887 Handle<JSObject>(holder)); 6887 Handle<JSObject>(holder));
6888 } 6888 }
6889 6889
6890 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 6890 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map);
6891 return BuildUncheckedMonomorphicElementAccess( 6891 return BuildUncheckedMonomorphicElementAccess(
6892 checked_object, key, val, 6892 checked_object, key, val,
6893 map->instance_type() == JS_ARRAY_TYPE, 6893 map->instance_type() == JS_ARRAY_TYPE,
6894 map->elements_kind(), access_type, 6894 map->elements_kind(), access_type,
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
7006 Handle<Map> map = maps->at(i); 7006 Handle<Map> map = maps->at(i);
7007 Handle<Map> transitioned_map = 7007 Handle<Map> transitioned_map =
7008 map->FindTransitionedMap(&possible_transitioned_maps); 7008 map->FindTransitionedMap(&possible_transitioned_maps);
7009 transition_target.Add(transitioned_map); 7009 transition_target.Add(transitioned_map);
7010 } 7010 }
7011 7011
7012 MapHandleList untransitionable_maps(maps->length()); 7012 MapHandleList untransitionable_maps(maps->length());
7013 HTransitionElementsKind* transition = NULL; 7013 HTransitionElementsKind* transition = NULL;
7014 for (int i = 0; i < maps->length(); ++i) { 7014 for (int i = 0; i < maps->length(); ++i) {
7015 Handle<Map> map = maps->at(i); 7015 Handle<Map> map = maps->at(i);
7016 ASSERT(map->IsMap()); 7016 DCHECK(map->IsMap());
7017 if (!transition_target.at(i).is_null()) { 7017 if (!transition_target.at(i).is_null()) {
7018 ASSERT(Map::IsValidElementsTransition( 7018 DCHECK(Map::IsValidElementsTransition(
7019 map->elements_kind(), 7019 map->elements_kind(),
7020 transition_target.at(i)->elements_kind())); 7020 transition_target.at(i)->elements_kind()));
7021 transition = Add<HTransitionElementsKind>(object, map, 7021 transition = Add<HTransitionElementsKind>(object, map,
7022 transition_target.at(i)); 7022 transition_target.at(i));
7023 } else { 7023 } else {
7024 untransitionable_maps.Add(map); 7024 untransitionable_maps.Add(map);
7025 } 7025 }
7026 } 7026 }
7027 7027
7028 // If only one map is left after transitioning, handle this case 7028 // If only one map is left after transitioning, handle this case
7029 // monomorphically. 7029 // monomorphically.
7030 ASSERT(untransitionable_maps.length() >= 1); 7030 DCHECK(untransitionable_maps.length() >= 1);
7031 if (untransitionable_maps.length() == 1) { 7031 if (untransitionable_maps.length() == 1) {
7032 Handle<Map> untransitionable_map = untransitionable_maps[0]; 7032 Handle<Map> untransitionable_map = untransitionable_maps[0];
7033 HInstruction* instr = NULL; 7033 HInstruction* instr = NULL;
7034 if (untransitionable_map->has_slow_elements_kind() || 7034 if (untransitionable_map->has_slow_elements_kind() ||
7035 !untransitionable_map->IsJSObjectMap()) { 7035 !untransitionable_map->IsJSObjectMap()) {
7036 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key, 7036 instr = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key,
7037 val)); 7037 val));
7038 } else { 7038 } else {
7039 instr = BuildMonomorphicElementAccess( 7039 instr = BuildMonomorphicElementAccess(
7040 object, key, val, transition, untransitionable_map, access_type, 7040 object, key, val, transition, untransitionable_map, access_type,
(...skipping 14 matching lines...) Expand all
7055 HCompareMap* mapcompare = 7055 HCompareMap* mapcompare =
7056 New<HCompareMap>(object, map, this_map, other_map); 7056 New<HCompareMap>(object, map, this_map, other_map);
7057 FinishCurrentBlock(mapcompare); 7057 FinishCurrentBlock(mapcompare);
7058 7058
7059 set_current_block(this_map); 7059 set_current_block(this_map);
7060 HInstruction* access = NULL; 7060 HInstruction* access = NULL;
7061 if (IsDictionaryElementsKind(elements_kind)) { 7061 if (IsDictionaryElementsKind(elements_kind)) {
7062 access = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key, 7062 access = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key,
7063 val)); 7063 val));
7064 } else { 7064 } else {
7065 ASSERT(IsFastElementsKind(elements_kind) || 7065 DCHECK(IsFastElementsKind(elements_kind) ||
7066 IsExternalArrayElementsKind(elements_kind) || 7066 IsExternalArrayElementsKind(elements_kind) ||
7067 IsFixedTypedArrayElementsKind(elements_kind)); 7067 IsFixedTypedArrayElementsKind(elements_kind));
7068 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 7068 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map);
7069 // Happily, mapcompare is a checked object. 7069 // Happily, mapcompare is a checked object.
7070 access = BuildUncheckedMonomorphicElementAccess( 7070 access = BuildUncheckedMonomorphicElementAccess(
7071 mapcompare, key, val, 7071 mapcompare, key, val,
7072 map->instance_type() == JS_ARRAY_TYPE, 7072 map->instance_type() == JS_ARRAY_TYPE,
7073 elements_kind, access_type, 7073 elements_kind, access_type,
7074 load_mode, 7074 load_mode,
7075 store_mode); 7075 store_mode);
7076 } 7076 }
7077 *has_side_effects |= access->HasObservableSideEffects(); 7077 *has_side_effects |= access->HasObservableSideEffects();
7078 // The caller will use has_side_effects and add a correct Simulate. 7078 // The caller will use has_side_effects and add a correct Simulate.
7079 access->SetFlag(HValue::kHasNoObservableSideEffects); 7079 access->SetFlag(HValue::kHasNoObservableSideEffects);
7080 if (access_type == LOAD) { 7080 if (access_type == LOAD) {
7081 Push(access); 7081 Push(access);
7082 } 7082 }
7083 NoObservableSideEffectsScope scope(this); 7083 NoObservableSideEffectsScope scope(this);
7084 GotoNoSimulate(join); 7084 GotoNoSimulate(join);
7085 set_current_block(other_map); 7085 set_current_block(other_map);
7086 } 7086 }
7087 7087
7088 // Ensure that we visited at least one map above that goes to join. This is 7088 // Ensure that we visited at least one map above that goes to join. This is
7089 // necessary because FinishExitWithHardDeoptimization does an AbnormalExit 7089 // necessary because FinishExitWithHardDeoptimization does an AbnormalExit
7090 // rather than joining the join block. If this becomes an issue, insert a 7090 // rather than joining the join block. If this becomes an issue, insert a
7091 // generic access in the case length() == 0. 7091 // generic access in the case length() == 0.
7092 ASSERT(join->predecessors()->length() > 0); 7092 DCHECK(join->predecessors()->length() > 0);
7093 // Deopt if none of the cases matched. 7093 // Deopt if none of the cases matched.
7094 NoObservableSideEffectsScope scope(this); 7094 NoObservableSideEffectsScope scope(this);
7095 FinishExitWithHardDeoptimization("Unknown map in polymorphic element access"); 7095 FinishExitWithHardDeoptimization("Unknown map in polymorphic element access");
7096 set_current_block(join); 7096 set_current_block(join);
7097 return access_type == STORE ? NULL : Pop(); 7097 return access_type == STORE ? NULL : Pop();
7098 } 7098 }
7099 7099
7100 7100
7101 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( 7101 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
7102 HValue* obj, 7102 HValue* obj,
7103 HValue* key, 7103 HValue* key,
7104 HValue* val, 7104 HValue* val,
7105 Expression* expr, 7105 Expression* expr,
7106 PropertyAccessType access_type, 7106 PropertyAccessType access_type,
7107 bool* has_side_effects) { 7107 bool* has_side_effects) {
7108 ASSERT(!expr->IsPropertyName()); 7108 DCHECK(!expr->IsPropertyName());
7109 HInstruction* instr = NULL; 7109 HInstruction* instr = NULL;
7110 7110
7111 SmallMapList* types; 7111 SmallMapList* types;
7112 bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone()); 7112 bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone());
7113 7113
7114 bool force_generic = false; 7114 bool force_generic = false;
7115 if (access_type == STORE && 7115 if (access_type == STORE &&
7116 (monomorphic || (types != NULL && !types->is_empty()))) { 7116 (monomorphic || (types != NULL && !types->is_empty()))) {
7117 // Stores can't be mono/polymorphic if their prototype chain has dictionary 7117 // Stores can't be mono/polymorphic if their prototype chain has dictionary
7118 // elements. However a receiver map that has dictionary elements itself 7118 // elements. However a receiver map that has dictionary elements itself
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
7243 PropertyAccessType access, 7243 PropertyAccessType access,
7244 BailoutId ast_id, 7244 BailoutId ast_id,
7245 BailoutId return_id, 7245 BailoutId return_id,
7246 Expression* expr, 7246 Expression* expr,
7247 HValue* object, 7247 HValue* object,
7248 Handle<String> name, 7248 Handle<String> name,
7249 HValue* value, 7249 HValue* value,
7250 bool is_uninitialized) { 7250 bool is_uninitialized) {
7251 SmallMapList* types; 7251 SmallMapList* types;
7252 ComputeReceiverTypes(expr, object, &types, zone()); 7252 ComputeReceiverTypes(expr, object, &types, zone());
7253 ASSERT(types != NULL); 7253 DCHECK(types != NULL);
7254 7254
7255 if (types->length() > 0) { 7255 if (types->length() > 0) {
7256 PropertyAccessInfo info(this, access, ToType(types->first()), name); 7256 PropertyAccessInfo info(this, access, ToType(types->first()), name);
7257 if (!info.CanAccessAsMonomorphic(types)) { 7257 if (!info.CanAccessAsMonomorphic(types)) {
7258 HandlePolymorphicNamedFieldAccess( 7258 HandlePolymorphicNamedFieldAccess(
7259 access, expr, ast_id, return_id, object, value, types, name); 7259 access, expr, ast_id, return_id, object, value, types, name);
7260 return NULL; 7260 return NULL;
7261 } 7261 }
7262 7262
7263 HValue* checked_object; 7263 HValue* checked_object;
7264 // Type::Number() is only supported by polymorphic load/call handling. 7264 // Type::Number() is only supported by polymorphic load/call handling.
7265 ASSERT(!info.type()->Is(Type::Number())); 7265 DCHECK(!info.type()->Is(Type::Number()));
7266 BuildCheckHeapObject(object); 7266 BuildCheckHeapObject(object);
7267 if (AreStringTypes(types)) { 7267 if (AreStringTypes(types)) {
7268 checked_object = 7268 checked_object =
7269 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING); 7269 Add<HCheckInstanceType>(object, HCheckInstanceType::IS_STRING);
7270 } else { 7270 } else {
7271 checked_object = Add<HCheckMaps>(object, types); 7271 checked_object = Add<HCheckMaps>(object, types);
7272 } 7272 }
7273 return BuildMonomorphicAccess( 7273 return BuildMonomorphicAccess(
7274 &info, object, checked_object, value, ast_id, return_id); 7274 &info, object, checked_object, value, ast_id, return_id);
7275 } 7275 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
7323 Drop(1); 7323 Drop(1);
7324 } 7324 }
7325 } 7325 }
7326 return ast_context()->ReturnValue(load); 7326 return ast_context()->ReturnValue(load);
7327 } 7327 }
7328 return ast_context()->ReturnInstruction(instr, ast_id); 7328 return ast_context()->ReturnInstruction(instr, ast_id);
7329 } 7329 }
7330 7330
7331 7331
7332 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { 7332 void HOptimizedGraphBuilder::VisitProperty(Property* expr) {
7333 ASSERT(!HasStackOverflow()); 7333 DCHECK(!HasStackOverflow());
7334 ASSERT(current_block() != NULL); 7334 DCHECK(current_block() != NULL);
7335 ASSERT(current_block()->HasPredecessor()); 7335 DCHECK(current_block()->HasPredecessor());
7336 7336
7337 if (TryArgumentsAccess(expr)) return; 7337 if (TryArgumentsAccess(expr)) return;
7338 7338
7339 CHECK_ALIVE(VisitForValue(expr->obj())); 7339 CHECK_ALIVE(VisitForValue(expr->obj()));
7340 if (!expr->key()->IsPropertyName() || expr->IsStringAccess()) { 7340 if (!expr->key()->IsPropertyName() || expr->IsStringAccess()) {
7341 CHECK_ALIVE(VisitForValue(expr->key())); 7341 CHECK_ALIVE(VisitForValue(expr->key()));
7342 } 7342 }
7343 7343
7344 BuildLoad(expr, expr->id()); 7344 BuildLoad(expr, expr->id());
7345 } 7345 }
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
7620 if (!ast_context()->IsEffect()) Push(call); 7620 if (!ast_context()->IsEffect()) Push(call);
7621 Goto(join); 7621 Goto(join);
7622 } else { 7622 } else {
7623 return ast_context()->ReturnInstruction(call, expr->id()); 7623 return ast_context()->ReturnInstruction(call, expr->id());
7624 } 7624 }
7625 } 7625 }
7626 7626
7627 // We assume that control flow is always live after an expression. So 7627 // We assume that control flow is always live after an expression. So
7628 // even without predecessors to the join block, we set it as the exit 7628 // even without predecessors to the join block, we set it as the exit
7629 // block and continue by adding instructions there. 7629 // block and continue by adding instructions there.
7630 ASSERT(join != NULL); 7630 DCHECK(join != NULL);
7631 if (join->HasPredecessor()) { 7631 if (join->HasPredecessor()) {
7632 set_current_block(join); 7632 set_current_block(join);
7633 join->SetJoinId(expr->id()); 7633 join->SetJoinId(expr->id());
7634 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop()); 7634 if (!ast_context()->IsEffect()) return ast_context()->ReturnValue(Pop());
7635 } else { 7635 } else {
7636 set_current_block(NULL); 7636 set_current_block(NULL);
7637 } 7637 }
7638 } 7638 }
7639 7639
7640 7640
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
7832 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, 7832 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG,
7833 &target_info, 7833 &target_info,
7834 target_shared); 7834 target_shared);
7835 } 7835 }
7836 7836
7837 // ---------------------------------------------------------------- 7837 // ----------------------------------------------------------------
7838 // After this point, we've made a decision to inline this function (so 7838 // After this point, we've made a decision to inline this function (so
7839 // TryInline should always return true). 7839 // TryInline should always return true).
7840 7840
7841 // Type-check the inlined function. 7841 // Type-check the inlined function.
7842 ASSERT(target_shared->has_deoptimization_support()); 7842 DCHECK(target_shared->has_deoptimization_support());
7843 AstTyper::Run(&target_info); 7843 AstTyper::Run(&target_info);
7844 7844
7845 int function_id = graph()->TraceInlinedFunction(target_shared, position); 7845 int function_id = graph()->TraceInlinedFunction(target_shared, position);
7846 7846
7847 // Save the pending call context. Set up new one for the inlined function. 7847 // Save the pending call context. Set up new one for the inlined function.
7848 // The function state is new-allocated because we need to delete it 7848 // The function state is new-allocated because we need to delete it
7849 // in two different places. 7849 // in two different places.
7850 FunctionState* target_state = new FunctionState( 7850 FunctionState* target_state = new FunctionState(
7851 this, &target_info, inlining_kind, function_id); 7851 this, &target_info, inlining_kind, function_id);
7852 7852
(...skipping 13 matching lines...) Expand all
7866 // current arguments values to use them for materialization. 7866 // current arguments values to use them for materialization.
7867 HEnvironment* arguments_env = inner_env->arguments_environment(); 7867 HEnvironment* arguments_env = inner_env->arguments_environment();
7868 int parameter_count = arguments_env->parameter_count(); 7868 int parameter_count = arguments_env->parameter_count();
7869 HArgumentsObject* arguments_object = Add<HArgumentsObject>(parameter_count); 7869 HArgumentsObject* arguments_object = Add<HArgumentsObject>(parameter_count);
7870 for (int i = 0; i < parameter_count; i++) { 7870 for (int i = 0; i < parameter_count; i++) {
7871 arguments_object->AddArgument(arguments_env->Lookup(i), zone()); 7871 arguments_object->AddArgument(arguments_env->Lookup(i), zone());
7872 } 7872 }
7873 7873
7874 // If the function uses arguments object then bind bind one. 7874 // If the function uses arguments object then bind bind one.
7875 if (function->scope()->arguments() != NULL) { 7875 if (function->scope()->arguments() != NULL) {
7876 ASSERT(function->scope()->arguments()->IsStackAllocated()); 7876 DCHECK(function->scope()->arguments()->IsStackAllocated());
7877 inner_env->Bind(function->scope()->arguments(), arguments_object); 7877 inner_env->Bind(function->scope()->arguments(), arguments_object);
7878 } 7878 }
7879 7879
7880 // Capture the state before invoking the inlined function for deopt in the 7880 // Capture the state before invoking the inlined function for deopt in the
7881 // inlined function. This simulate has no bailout-id since it's not directly 7881 // inlined function. This simulate has no bailout-id since it's not directly
7882 // reachable for deopt, and is only used to capture the state. If the simulate 7882 // reachable for deopt, and is only used to capture the state. If the simulate
7883 // becomes reachable by merging, the ast id of the simulate merged into it is 7883 // becomes reachable by merging, the ast id of the simulate merged into it is
7884 // adopted. 7884 // adopted.
7885 Add<HSimulate>(BailoutId::None()); 7885 Add<HSimulate>(BailoutId::None());
7886 7886
(...skipping 17 matching lines...) Expand all
7904 target_shared->DisableOptimization(kInliningBailedOut); 7904 target_shared->DisableOptimization(kInliningBailedOut);
7905 inline_bailout_ = true; 7905 inline_bailout_ = true;
7906 delete target_state; 7906 delete target_state;
7907 return true; 7907 return true;
7908 } 7908 }
7909 7909
7910 // Update inlined nodes count. 7910 // Update inlined nodes count.
7911 inlined_count_ += nodes_added; 7911 inlined_count_ += nodes_added;
7912 7912
7913 Handle<Code> unoptimized_code(target_shared->code()); 7913 Handle<Code> unoptimized_code(target_shared->code());
7914 ASSERT(unoptimized_code->kind() == Code::FUNCTION); 7914 DCHECK(unoptimized_code->kind() == Code::FUNCTION);
7915 Handle<TypeFeedbackInfo> type_info( 7915 Handle<TypeFeedbackInfo> type_info(
7916 TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info())); 7916 TypeFeedbackInfo::cast(unoptimized_code->type_feedback_info()));
7917 graph()->update_type_change_checksum(type_info->own_type_change_checksum()); 7917 graph()->update_type_change_checksum(type_info->own_type_change_checksum());
7918 7918
7919 TraceInline(target, caller, NULL); 7919 TraceInline(target, caller, NULL);
7920 7920
7921 if (current_block() != NULL) { 7921 if (current_block() != NULL) {
7922 FunctionState* state = function_state(); 7922 FunctionState* state = function_state();
7923 if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) { 7923 if (state->inlining_kind() == CONSTRUCT_CALL_RETURN) {
7924 // Falling off the end of an inlined construct call. In a test context the 7924 // Falling off the end of an inlined construct call. In a test context the
7925 // return value will always evaluate to true, in a value context the 7925 // return value will always evaluate to true, in a value context the
7926 // return value is the newly allocated receiver. 7926 // return value is the newly allocated receiver.
7927 if (call_context()->IsTest()) { 7927 if (call_context()->IsTest()) {
7928 Goto(inlined_test_context()->if_true(), state); 7928 Goto(inlined_test_context()->if_true(), state);
7929 } else if (call_context()->IsEffect()) { 7929 } else if (call_context()->IsEffect()) {
7930 Goto(function_return(), state); 7930 Goto(function_return(), state);
7931 } else { 7931 } else {
7932 ASSERT(call_context()->IsValue()); 7932 DCHECK(call_context()->IsValue());
7933 AddLeaveInlined(implicit_return_value, state); 7933 AddLeaveInlined(implicit_return_value, state);
7934 } 7934 }
7935 } else if (state->inlining_kind() == SETTER_CALL_RETURN) { 7935 } else if (state->inlining_kind() == SETTER_CALL_RETURN) {
7936 // Falling off the end of an inlined setter call. The returned value is 7936 // Falling off the end of an inlined setter call. The returned value is
7937 // never used, the value of an assignment is always the value of the RHS 7937 // never used, the value of an assignment is always the value of the RHS
7938 // of the assignment. 7938 // of the assignment.
7939 if (call_context()->IsTest()) { 7939 if (call_context()->IsTest()) {
7940 inlined_test_context()->ReturnValue(implicit_return_value); 7940 inlined_test_context()->ReturnValue(implicit_return_value);
7941 } else if (call_context()->IsEffect()) { 7941 } else if (call_context()->IsEffect()) {
7942 Goto(function_return(), state); 7942 Goto(function_return(), state);
7943 } else { 7943 } else {
7944 ASSERT(call_context()->IsValue()); 7944 DCHECK(call_context()->IsValue());
7945 AddLeaveInlined(implicit_return_value, state); 7945 AddLeaveInlined(implicit_return_value, state);
7946 } 7946 }
7947 } else { 7947 } else {
7948 // Falling off the end of a normal inlined function. This basically means 7948 // Falling off the end of a normal inlined function. This basically means
7949 // returning undefined. 7949 // returning undefined.
7950 if (call_context()->IsTest()) { 7950 if (call_context()->IsTest()) {
7951 Goto(inlined_test_context()->if_false(), state); 7951 Goto(inlined_test_context()->if_false(), state);
7952 } else if (call_context()->IsEffect()) { 7952 } else if (call_context()->IsEffect()) {
7953 Goto(function_return(), state); 7953 Goto(function_return(), state);
7954 } else { 7954 } else {
7955 ASSERT(call_context()->IsValue()); 7955 DCHECK(call_context()->IsValue());
7956 AddLeaveInlined(undefined, state); 7956 AddLeaveInlined(undefined, state);
7957 } 7957 }
7958 } 7958 }
7959 } 7959 }
7960 7960
7961 // Fix up the function exits. 7961 // Fix up the function exits.
7962 if (inlined_test_context() != NULL) { 7962 if (inlined_test_context() != NULL) {
7963 HBasicBlock* if_true = inlined_test_context()->if_true(); 7963 HBasicBlock* if_true = inlined_test_context()->if_true();
7964 HBasicBlock* if_false = inlined_test_context()->if_false(); 7964 HBasicBlock* if_false = inlined_test_context()->if_false();
7965 7965
7966 HEnterInlined* entry = function_state()->entry(); 7966 HEnterInlined* entry = function_state()->entry();
7967 7967
7968 // Pop the return test context from the expression context stack. 7968 // Pop the return test context from the expression context stack.
7969 ASSERT(ast_context() == inlined_test_context()); 7969 DCHECK(ast_context() == inlined_test_context());
7970 ClearInlinedTestContext(); 7970 ClearInlinedTestContext();
7971 delete target_state; 7971 delete target_state;
7972 7972
7973 // Forward to the real test context. 7973 // Forward to the real test context.
7974 if (if_true->HasPredecessor()) { 7974 if (if_true->HasPredecessor()) {
7975 entry->RegisterReturnTarget(if_true, zone()); 7975 entry->RegisterReturnTarget(if_true, zone());
7976 if_true->SetJoinId(ast_id); 7976 if_true->SetJoinId(ast_id);
7977 HBasicBlock* true_target = TestContext::cast(ast_context())->if_true(); 7977 HBasicBlock* true_target = TestContext::cast(ast_context())->if_true();
7978 Goto(if_true, true_target, function_state()); 7978 Goto(if_true, true_target, function_state());
7979 } 7979 }
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
8168 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { 8168 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) {
8169 double exponent = HConstant::cast(right)->DoubleValue(); 8169 double exponent = HConstant::cast(right)->DoubleValue();
8170 if (exponent == 0.5) { 8170 if (exponent == 0.5) {
8171 result = NewUncasted<HUnaryMathOperation>(left, kMathPowHalf); 8171 result = NewUncasted<HUnaryMathOperation>(left, kMathPowHalf);
8172 } else if (exponent == -0.5) { 8172 } else if (exponent == -0.5) {
8173 HValue* one = graph()->GetConstant1(); 8173 HValue* one = graph()->GetConstant1();
8174 HInstruction* sqrt = AddUncasted<HUnaryMathOperation>( 8174 HInstruction* sqrt = AddUncasted<HUnaryMathOperation>(
8175 left, kMathPowHalf); 8175 left, kMathPowHalf);
8176 // MathPowHalf doesn't have side effects so there's no need for 8176 // MathPowHalf doesn't have side effects so there's no need for
8177 // an environment simulation here. 8177 // an environment simulation here.
8178 ASSERT(!sqrt->HasObservableSideEffects()); 8178 DCHECK(!sqrt->HasObservableSideEffects());
8179 result = NewUncasted<HDiv>(one, sqrt); 8179 result = NewUncasted<HDiv>(one, sqrt);
8180 } else if (exponent == 2.0) { 8180 } else if (exponent == 2.0) {
8181 result = NewUncasted<HMul>(left, left); 8181 result = NewUncasted<HMul>(left, left);
8182 } 8182 }
8183 } 8183 }
8184 8184
8185 if (result == NULL) { 8185 if (result == NULL) {
8186 result = NewUncasted<HPower>(left, right); 8186 result = NewUncasted<HPower>(left, right);
8187 } 8187 }
8188 ast_context()->ReturnInstruction(result, expr->id()); 8188 ast_context()->ReturnInstruction(result, expr->id());
(...skipping 22 matching lines...) Expand all
8211 ast_context()->ReturnInstruction(result, expr->id()); 8211 ast_context()->ReturnInstruction(result, expr->id());
8212 return true; 8212 return true;
8213 } 8213 }
8214 break; 8214 break;
8215 case kArrayPop: { 8215 case kArrayPop: {
8216 if (receiver_map.is_null()) return false; 8216 if (receiver_map.is_null()) return false;
8217 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; 8217 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
8218 ElementsKind elements_kind = receiver_map->elements_kind(); 8218 ElementsKind elements_kind = receiver_map->elements_kind();
8219 if (!IsFastElementsKind(elements_kind)) return false; 8219 if (!IsFastElementsKind(elements_kind)) return false;
8220 if (receiver_map->is_observed()) return false; 8220 if (receiver_map->is_observed()) return false;
8221 ASSERT(receiver_map->is_extensible()); 8221 DCHECK(receiver_map->is_extensible());
8222 8222
8223 Drop(expr->arguments()->length()); 8223 Drop(expr->arguments()->length());
8224 HValue* result; 8224 HValue* result;
8225 HValue* reduced_length; 8225 HValue* reduced_length;
8226 HValue* receiver = Pop(); 8226 HValue* receiver = Pop();
8227 8227
8228 HValue* checked_object = AddCheckMap(receiver, receiver_map); 8228 HValue* checked_object = AddCheckMap(receiver, receiver_map);
8229 HValue* length = Add<HLoadNamedField>( 8229 HValue* length = Add<HLoadNamedField>(
8230 checked_object, static_cast<HValue*>(NULL), 8230 checked_object, static_cast<HValue*>(NULL),
8231 HObjectAccess::ForArrayLength(elements_kind)); 8231 HObjectAccess::ForArrayLength(elements_kind));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
8276 ast_context()->ReturnValue(result); 8276 ast_context()->ReturnValue(result);
8277 return true; 8277 return true;
8278 } 8278 }
8279 case kArrayPush: { 8279 case kArrayPush: {
8280 if (receiver_map.is_null()) return false; 8280 if (receiver_map.is_null()) return false;
8281 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; 8281 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
8282 ElementsKind elements_kind = receiver_map->elements_kind(); 8282 ElementsKind elements_kind = receiver_map->elements_kind();
8283 if (!IsFastElementsKind(elements_kind)) return false; 8283 if (!IsFastElementsKind(elements_kind)) return false;
8284 if (receiver_map->is_observed()) return false; 8284 if (receiver_map->is_observed()) return false;
8285 if (JSArray::IsReadOnlyLengthDescriptor(receiver_map)) return false; 8285 if (JSArray::IsReadOnlyLengthDescriptor(receiver_map)) return false;
8286 ASSERT(receiver_map->is_extensible()); 8286 DCHECK(receiver_map->is_extensible());
8287 8287
8288 // If there may be elements accessors in the prototype chain, the fast 8288 // If there may be elements accessors in the prototype chain, the fast
8289 // inlined version can't be used. 8289 // inlined version can't be used.
8290 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; 8290 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false;
8291 // If there currently can be no elements accessors on the prototype chain, 8291 // If there currently can be no elements accessors on the prototype chain,
8292 // it doesn't mean that there won't be any later. Install a full prototype 8292 // it doesn't mean that there won't be any later. Install a full prototype
8293 // chain check to trap element accessors being installed on the prototype 8293 // chain check to trap element accessors being installed on the prototype
8294 // chain, which would cause elements to go to dictionary mode and result 8294 // chain, which would cause elements to go to dictionary mode and result
8295 // in a map change. 8295 // in a map change.
8296 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 8296 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
8328 8328
8329 ast_context()->ReturnValue(new_size); 8329 ast_context()->ReturnValue(new_size);
8330 return true; 8330 return true;
8331 } 8331 }
8332 case kArrayShift: { 8332 case kArrayShift: {
8333 if (receiver_map.is_null()) return false; 8333 if (receiver_map.is_null()) return false;
8334 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; 8334 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
8335 ElementsKind kind = receiver_map->elements_kind(); 8335 ElementsKind kind = receiver_map->elements_kind();
8336 if (!IsFastElementsKind(kind)) return false; 8336 if (!IsFastElementsKind(kind)) return false;
8337 if (receiver_map->is_observed()) return false; 8337 if (receiver_map->is_observed()) return false;
8338 ASSERT(receiver_map->is_extensible()); 8338 DCHECK(receiver_map->is_extensible());
8339 8339
8340 // If there may be elements accessors in the prototype chain, the fast 8340 // If there may be elements accessors in the prototype chain, the fast
8341 // inlined version can't be used. 8341 // inlined version can't be used.
8342 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; 8342 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false;
8343 8343
8344 // If there currently can be no elements accessors on the prototype chain, 8344 // If there currently can be no elements accessors on the prototype chain,
8345 // it doesn't mean that there won't be any later. Install a full prototype 8345 // it doesn't mean that there won't be any later. Install a full prototype
8346 // chain check to trap element accessors being installed on the prototype 8346 // chain check to trap element accessors being installed on the prototype
8347 // chain, which would cause elements to go to dictionary mode and result 8347 // chain, which would cause elements to go to dictionary mode and result
8348 // in a map change. 8348 // in a map change.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
8443 return true; 8443 return true;
8444 } 8444 }
8445 case kArrayIndexOf: 8445 case kArrayIndexOf:
8446 case kArrayLastIndexOf: { 8446 case kArrayLastIndexOf: {
8447 if (receiver_map.is_null()) return false; 8447 if (receiver_map.is_null()) return false;
8448 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false; 8448 if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
8449 ElementsKind kind = receiver_map->elements_kind(); 8449 ElementsKind kind = receiver_map->elements_kind();
8450 if (!IsFastElementsKind(kind)) return false; 8450 if (!IsFastElementsKind(kind)) return false;
8451 if (receiver_map->is_observed()) return false; 8451 if (receiver_map->is_observed()) return false;
8452 if (argument_count != 2) return false; 8452 if (argument_count != 2) return false;
8453 ASSERT(receiver_map->is_extensible()); 8453 DCHECK(receiver_map->is_extensible());
8454 8454
8455 // If there may be elements accessors in the prototype chain, the fast 8455 // If there may be elements accessors in the prototype chain, the fast
8456 // inlined version can't be used. 8456 // inlined version can't be used.
8457 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false; 8457 if (receiver_map->DictionaryElementsInPrototypeChainOnly()) return false;
8458 8458
8459 // If there currently can be no elements accessors on the prototype chain, 8459 // If there currently can be no elements accessors on the prototype chain,
8460 // it doesn't mean that there won't be any later. Install a full prototype 8460 // it doesn't mean that there won't be any later. Install a full prototype
8461 // chain check to trap element accessors being installed on the prototype 8461 // chain check to trap element accessors being installed on the prototype
8462 // chain, which would cause elements to go to dictionary mode and result 8462 // chain, which would cause elements to go to dictionary mode and result
8463 // in a map change. 8463 // in a map change.
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
8550 int argc, 8550 int argc,
8551 BailoutId ast_id, 8551 BailoutId ast_id,
8552 ApiCallType call_type) { 8552 ApiCallType call_type) {
8553 CallOptimization optimization(function); 8553 CallOptimization optimization(function);
8554 if (!optimization.is_simple_api_call()) return false; 8554 if (!optimization.is_simple_api_call()) return false;
8555 Handle<Map> holder_map; 8555 Handle<Map> holder_map;
8556 if (call_type == kCallApiFunction) { 8556 if (call_type == kCallApiFunction) {
8557 // Cannot embed a direct reference to the global proxy map 8557 // Cannot embed a direct reference to the global proxy map
8558 // as it maybe dropped on deserialization. 8558 // as it maybe dropped on deserialization.
8559 CHECK(!isolate()->serializer_enabled()); 8559 CHECK(!isolate()->serializer_enabled());
8560 ASSERT_EQ(0, receiver_maps->length()); 8560 DCHECK_EQ(0, receiver_maps->length());
8561 receiver_maps->Add(handle(function->global_proxy()->map()), zone()); 8561 receiver_maps->Add(handle(function->global_proxy()->map()), zone());
8562 } 8562 }
8563 CallOptimization::HolderLookup holder_lookup = 8563 CallOptimization::HolderLookup holder_lookup =
8564 CallOptimization::kHolderNotFound; 8564 CallOptimization::kHolderNotFound;
8565 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( 8565 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType(
8566 receiver_maps->first(), &holder_lookup); 8566 receiver_maps->first(), &holder_lookup);
8567 if (holder_lookup == CallOptimization::kHolderNotFound) return false; 8567 if (holder_lookup == CallOptimization::kHolderNotFound) return false;
8568 8568
8569 if (FLAG_trace_inlining) { 8569 if (FLAG_trace_inlining) {
8570 PrintF("Inlining api function "); 8570 PrintF("Inlining api function ");
8571 function->ShortPrint(); 8571 function->ShortPrint();
8572 PrintF("\n"); 8572 PrintF("\n");
8573 } 8573 }
8574 8574
8575 bool drop_extra = false; 8575 bool drop_extra = false;
8576 bool is_store = false; 8576 bool is_store = false;
8577 switch (call_type) { 8577 switch (call_type) {
8578 case kCallApiFunction: 8578 case kCallApiFunction:
8579 case kCallApiMethod: 8579 case kCallApiMethod:
8580 // Need to check that none of the receiver maps could have changed. 8580 // Need to check that none of the receiver maps could have changed.
8581 Add<HCheckMaps>(receiver, receiver_maps); 8581 Add<HCheckMaps>(receiver, receiver_maps);
8582 // Need to ensure the chain between receiver and api_holder is intact. 8582 // Need to ensure the chain between receiver and api_holder is intact.
8583 if (holder_lookup == CallOptimization::kHolderFound) { 8583 if (holder_lookup == CallOptimization::kHolderFound) {
8584 AddCheckPrototypeMaps(api_holder, receiver_maps->first()); 8584 AddCheckPrototypeMaps(api_holder, receiver_maps->first());
8585 } else { 8585 } else {
8586 ASSERT_EQ(holder_lookup, CallOptimization::kHolderIsReceiver); 8586 DCHECK_EQ(holder_lookup, CallOptimization::kHolderIsReceiver);
8587 } 8587 }
8588 // Includes receiver. 8588 // Includes receiver.
8589 PushArgumentsFromEnvironment(argc + 1); 8589 PushArgumentsFromEnvironment(argc + 1);
8590 // Drop function after call. 8590 // Drop function after call.
8591 drop_extra = true; 8591 drop_extra = true;
8592 break; 8592 break;
8593 case kCallApiGetter: 8593 case kCallApiGetter:
8594 // Receiver and prototype chain cannot have changed. 8594 // Receiver and prototype chain cannot have changed.
8595 ASSERT_EQ(0, argc); 8595 DCHECK_EQ(0, argc);
8596 ASSERT_EQ(NULL, receiver); 8596 DCHECK_EQ(NULL, receiver);
8597 // Receiver is on expression stack. 8597 // Receiver is on expression stack.
8598 receiver = Pop(); 8598 receiver = Pop();
8599 Add<HPushArguments>(receiver); 8599 Add<HPushArguments>(receiver);
8600 break; 8600 break;
8601 case kCallApiSetter: 8601 case kCallApiSetter:
8602 { 8602 {
8603 is_store = true; 8603 is_store = true;
8604 // Receiver and prototype chain cannot have changed. 8604 // Receiver and prototype chain cannot have changed.
8605 ASSERT_EQ(1, argc); 8605 DCHECK_EQ(1, argc);
8606 ASSERT_EQ(NULL, receiver); 8606 DCHECK_EQ(NULL, receiver);
8607 // Receiver and value are on expression stack. 8607 // Receiver and value are on expression stack.
8608 HValue* value = Pop(); 8608 HValue* value = Pop();
8609 receiver = Pop(); 8609 receiver = Pop();
8610 Add<HPushArguments>(receiver, value); 8610 Add<HPushArguments>(receiver, value);
8611 break; 8611 break;
8612 } 8612 }
8613 } 8613 }
8614 8614
8615 HValue* holder = NULL; 8615 HValue* holder = NULL;
8616 switch (holder_lookup) { 8616 switch (holder_lookup) {
(...skipping 25 matching lines...) Expand all
8642 api_function_address 8642 api_function_address
8643 }; 8643 };
8644 8644
8645 CallInterfaceDescriptor* descriptor = 8645 CallInterfaceDescriptor* descriptor =
8646 isolate()->call_descriptor(Isolate::ApiFunctionCall); 8646 isolate()->call_descriptor(Isolate::ApiFunctionCall);
8647 8647
8648 CallApiFunctionStub stub(isolate(), is_store, call_data_is_undefined, argc); 8648 CallApiFunctionStub stub(isolate(), is_store, call_data_is_undefined, argc);
8649 Handle<Code> code = stub.GetCode(); 8649 Handle<Code> code = stub.GetCode();
8650 HConstant* code_value = Add<HConstant>(code); 8650 HConstant* code_value = Add<HConstant>(code);
8651 8651
8652 ASSERT((sizeof(op_vals) / kPointerSize) == 8652 DCHECK((sizeof(op_vals) / kPointerSize) ==
8653 descriptor->GetEnvironmentLength()); 8653 descriptor->GetEnvironmentLength());
8654 8654
8655 HInstruction* call = New<HCallWithDescriptor>( 8655 HInstruction* call = New<HCallWithDescriptor>(
8656 code_value, argc + 1, descriptor, 8656 code_value, argc + 1, descriptor,
8657 Vector<HValue*>(op_vals, descriptor->GetEnvironmentLength())); 8657 Vector<HValue*>(op_vals, descriptor->GetEnvironmentLength()));
8658 8658
8659 if (drop_extra) Drop(1); // Drop function. 8659 if (drop_extra) Drop(1); // Drop function.
8660 ast_context()->ReturnInstruction(call, ast_id); 8660 ast_context()->ReturnInstruction(call, ast_id);
8661 return true; 8661 return true;
8662 } 8662 }
8663 8663
8664 8664
8665 bool HOptimizedGraphBuilder::TryCallApply(Call* expr) { 8665 bool HOptimizedGraphBuilder::TryCallApply(Call* expr) {
8666 ASSERT(expr->expression()->IsProperty()); 8666 DCHECK(expr->expression()->IsProperty());
8667 8667
8668 if (!expr->IsMonomorphic()) { 8668 if (!expr->IsMonomorphic()) {
8669 return false; 8669 return false;
8670 } 8670 }
8671 Handle<Map> function_map = expr->GetReceiverTypes()->first(); 8671 Handle<Map> function_map = expr->GetReceiverTypes()->first();
8672 if (function_map->instance_type() != JS_FUNCTION_TYPE || 8672 if (function_map->instance_type() != JS_FUNCTION_TYPE ||
8673 !expr->target()->shared()->HasBuiltinFunctionId() || 8673 !expr->target()->shared()->HasBuiltinFunctionId() ||
8674 expr->target()->shared()->builtin_function_id() != kFunctionApply) { 8674 expr->target()->shared()->builtin_function_id() != kFunctionApply) {
8675 return false; 8675 return false;
8676 } 8676 }
(...skipping 22 matching lines...) Expand all
8699 HValue* wrapped_receiver = BuildWrapReceiver(receiver, checked_function); 8699 HValue* wrapped_receiver = BuildWrapReceiver(receiver, checked_function);
8700 HInstruction* result = New<HApplyArguments>(function, 8700 HInstruction* result = New<HApplyArguments>(function,
8701 wrapped_receiver, 8701 wrapped_receiver,
8702 length, 8702 length,
8703 elements); 8703 elements);
8704 ast_context()->ReturnInstruction(result, expr->id()); 8704 ast_context()->ReturnInstruction(result, expr->id());
8705 return true; 8705 return true;
8706 } else { 8706 } else {
8707 // We are inside inlined function and we know exactly what is inside 8707 // We are inside inlined function and we know exactly what is inside
8708 // arguments object. But we need to be able to materialize at deopt. 8708 // arguments object. But we need to be able to materialize at deopt.
8709 ASSERT_EQ(environment()->arguments_environment()->parameter_count(), 8709 DCHECK_EQ(environment()->arguments_environment()->parameter_count(),
8710 function_state()->entry()->arguments_object()->arguments_count()); 8710 function_state()->entry()->arguments_object()->arguments_count());
8711 HArgumentsObject* args = function_state()->entry()->arguments_object(); 8711 HArgumentsObject* args = function_state()->entry()->arguments_object();
8712 const ZoneList<HValue*>* arguments_values = args->arguments_values(); 8712 const ZoneList<HValue*>* arguments_values = args->arguments_values();
8713 int arguments_count = arguments_values->length(); 8713 int arguments_count = arguments_values->length();
8714 Push(function); 8714 Push(function);
8715 Push(BuildWrapReceiver(receiver, checked_function)); 8715 Push(BuildWrapReceiver(receiver, checked_function));
8716 for (int i = 1; i < arguments_count; i++) { 8716 for (int i = 1; i < arguments_count; i++) {
8717 Push(arguments_values->at(i)); 8717 Push(arguments_values->at(i));
8718 } 8718 }
8719 8719
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
8767 Drop(1); 8767 Drop(1);
8768 } 8768 }
8769 ast_context()->ReturnInstruction(call, expression->id()); 8769 ast_context()->ReturnInstruction(call, expression->id());
8770 } 8770 }
8771 8771
8772 8772
8773 HValue* HOptimizedGraphBuilder::BuildArrayIndexOf(HValue* receiver, 8773 HValue* HOptimizedGraphBuilder::BuildArrayIndexOf(HValue* receiver,
8774 HValue* search_element, 8774 HValue* search_element,
8775 ElementsKind kind, 8775 ElementsKind kind,
8776 ArrayIndexOfMode mode) { 8776 ArrayIndexOfMode mode) {
8777 ASSERT(IsFastElementsKind(kind)); 8777 DCHECK(IsFastElementsKind(kind));
8778 8778
8779 NoObservableSideEffectsScope no_effects(this); 8779 NoObservableSideEffectsScope no_effects(this);
8780 8780
8781 HValue* elements = AddLoadElements(receiver); 8781 HValue* elements = AddLoadElements(receiver);
8782 HValue* length = AddLoadArrayLength(receiver, kind); 8782 HValue* length = AddLoadArrayLength(receiver, kind);
8783 8783
8784 HValue* initial; 8784 HValue* initial;
8785 HValue* terminating; 8785 HValue* terminating;
8786 Token::Value token; 8786 Token::Value token;
8787 LoopBuilder::Direction direction; 8787 LoopBuilder::Direction direction;
8788 if (mode == kFirstIndexOf) { 8788 if (mode == kFirstIndexOf) {
8789 initial = graph()->GetConstant0(); 8789 initial = graph()->GetConstant0();
8790 terminating = length; 8790 terminating = length;
8791 token = Token::LT; 8791 token = Token::LT;
8792 direction = LoopBuilder::kPostIncrement; 8792 direction = LoopBuilder::kPostIncrement;
8793 } else { 8793 } else {
8794 ASSERT_EQ(kLastIndexOf, mode); 8794 DCHECK_EQ(kLastIndexOf, mode);
8795 initial = length; 8795 initial = length;
8796 terminating = graph()->GetConstant0(); 8796 terminating = graph()->GetConstant0();
8797 token = Token::GT; 8797 token = Token::GT;
8798 direction = LoopBuilder::kPreDecrement; 8798 direction = LoopBuilder::kPreDecrement;
8799 } 8799 }
8800 8800
8801 Push(graph()->GetConstantMinus1()); 8801 Push(graph()->GetConstantMinus1());
8802 if (IsFastDoubleElementsKind(kind) || IsFastSmiElementsKind(kind)) { 8802 if (IsFastDoubleElementsKind(kind) || IsFastSmiElementsKind(kind)) {
8803 LoopBuilder loop(this, context(), direction); 8803 LoopBuilder loop(this, context(), direction);
8804 { 8804 {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
8943 8943
8944 BuildArrayCall(expr, 8944 BuildArrayCall(expr,
8945 expr->arguments()->length(), 8945 expr->arguments()->length(),
8946 function, 8946 function,
8947 expr->allocation_site()); 8947 expr->allocation_site());
8948 return true; 8948 return true;
8949 } 8949 }
8950 8950
8951 8951
8952 void HOptimizedGraphBuilder::VisitCall(Call* expr) { 8952 void HOptimizedGraphBuilder::VisitCall(Call* expr) {
8953 ASSERT(!HasStackOverflow()); 8953 DCHECK(!HasStackOverflow());
8954 ASSERT(current_block() != NULL); 8954 DCHECK(current_block() != NULL);
8955 ASSERT(current_block()->HasPredecessor()); 8955 DCHECK(current_block()->HasPredecessor());
8956 Expression* callee = expr->expression(); 8956 Expression* callee = expr->expression();
8957 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 8957 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
8958 HInstruction* call = NULL; 8958 HInstruction* call = NULL;
8959 8959
8960 Property* prop = callee->AsProperty(); 8960 Property* prop = callee->AsProperty();
8961 if (prop != NULL) { 8961 if (prop != NULL) {
8962 CHECK_ALIVE(VisitForValue(prop->obj())); 8962 CHECK_ALIVE(VisitForValue(prop->obj()));
8963 HValue* receiver = Top(); 8963 HValue* receiver = Top();
8964 8964
8965 SmallMapList* types; 8965 SmallMapList* types;
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
9124 9124
9125 Drop(1); // Drop the function. 9125 Drop(1); // Drop the function.
9126 return ast_context()->ReturnInstruction(call, expr->id()); 9126 return ast_context()->ReturnInstruction(call, expr->id());
9127 } 9127 }
9128 9128
9129 9129
9130 void HOptimizedGraphBuilder::BuildInlinedCallArray( 9130 void HOptimizedGraphBuilder::BuildInlinedCallArray(
9131 Expression* expression, 9131 Expression* expression,
9132 int argument_count, 9132 int argument_count,
9133 Handle<AllocationSite> site) { 9133 Handle<AllocationSite> site) {
9134 ASSERT(!site.is_null()); 9134 DCHECK(!site.is_null());
9135 ASSERT(argument_count >= 0 && argument_count <= 1); 9135 DCHECK(argument_count >= 0 && argument_count <= 1);
9136 NoObservableSideEffectsScope no_effects(this); 9136 NoObservableSideEffectsScope no_effects(this);
9137 9137
9138 // We should at least have the constructor on the expression stack. 9138 // We should at least have the constructor on the expression stack.
9139 HValue* constructor = environment()->ExpressionStackAt(argument_count); 9139 HValue* constructor = environment()->ExpressionStackAt(argument_count);
9140 9140
9141 // Register on the site for deoptimization if the transition feedback changes. 9141 // Register on the site for deoptimization if the transition feedback changes.
9142 AllocationSite::AddDependentCompilationInfo( 9142 AllocationSite::AddDependentCompilationInfo(
9143 site, AllocationSite::TRANSITIONS, top_info()); 9143 site, AllocationSite::TRANSITIONS, top_info());
9144 ElementsKind kind = site->GetElementsKind(); 9144 ElementsKind kind = site->GetElementsKind();
9145 HInstruction* site_instruction = Add<HConstant>(site); 9145 HInstruction* site_instruction = Add<HConstant>(site);
9146 9146
9147 // In the single constant argument case, we may have to adjust elements kind 9147 // In the single constant argument case, we may have to adjust elements kind
9148 // to avoid creating a packed non-empty array. 9148 // to avoid creating a packed non-empty array.
9149 if (argument_count == 1 && !IsHoleyElementsKind(kind)) { 9149 if (argument_count == 1 && !IsHoleyElementsKind(kind)) {
9150 HValue* argument = environment()->Top(); 9150 HValue* argument = environment()->Top();
9151 if (argument->IsConstant()) { 9151 if (argument->IsConstant()) {
9152 HConstant* constant_argument = HConstant::cast(argument); 9152 HConstant* constant_argument = HConstant::cast(argument);
9153 ASSERT(constant_argument->HasSmiValue()); 9153 DCHECK(constant_argument->HasSmiValue());
9154 int constant_array_size = constant_argument->Integer32Value(); 9154 int constant_array_size = constant_argument->Integer32Value();
9155 if (constant_array_size != 0) { 9155 if (constant_array_size != 0) {
9156 kind = GetHoleyElementsKind(kind); 9156 kind = GetHoleyElementsKind(kind);
9157 } 9157 }
9158 } 9158 }
9159 } 9159 }
9160 9160
9161 // Build the array. 9161 // Build the array.
9162 JSArrayBuilder array_builder(this, 9162 JSArrayBuilder array_builder(this,
9163 kind, 9163 kind,
(...skipping 18 matching lines...) Expand all
9182 constructor->initial_map()->InitialPropertiesLength() == 0; 9182 constructor->initial_map()->InitialPropertiesLength() == 0;
9183 } 9183 }
9184 9184
9185 9185
9186 bool HOptimizedGraphBuilder::IsCallArrayInlineable( 9186 bool HOptimizedGraphBuilder::IsCallArrayInlineable(
9187 int argument_count, 9187 int argument_count,
9188 Handle<AllocationSite> site) { 9188 Handle<AllocationSite> site) {
9189 Handle<JSFunction> caller = current_info()->closure(); 9189 Handle<JSFunction> caller = current_info()->closure();
9190 Handle<JSFunction> target = array_function(); 9190 Handle<JSFunction> target = array_function();
9191 // We should have the function plus array arguments on the environment stack. 9191 // We should have the function plus array arguments on the environment stack.
9192 ASSERT(environment()->length() >= (argument_count + 1)); 9192 DCHECK(environment()->length() >= (argument_count + 1));
9193 ASSERT(!site.is_null()); 9193 DCHECK(!site.is_null());
9194 9194
9195 bool inline_ok = false; 9195 bool inline_ok = false;
9196 if (site->CanInlineCall()) { 9196 if (site->CanInlineCall()) {
9197 // We also want to avoid inlining in certain 1 argument scenarios. 9197 // We also want to avoid inlining in certain 1 argument scenarios.
9198 if (argument_count == 1) { 9198 if (argument_count == 1) {
9199 HValue* argument = Top(); 9199 HValue* argument = Top();
9200 if (argument->IsConstant()) { 9200 if (argument->IsConstant()) {
9201 // Do not inline if the constant length argument is not a smi or 9201 // Do not inline if the constant length argument is not a smi or
9202 // outside the valid range for unrolled loop initialization. 9202 // outside the valid range for unrolled loop initialization.
9203 HConstant* constant_argument = HConstant::cast(argument); 9203 HConstant* constant_argument = HConstant::cast(argument);
(...skipping 19 matching lines...) Expand all
9223 } 9223 }
9224 9224
9225 if (inline_ok) { 9225 if (inline_ok) {
9226 TraceInline(target, caller, NULL); 9226 TraceInline(target, caller, NULL);
9227 } 9227 }
9228 return inline_ok; 9228 return inline_ok;
9229 } 9229 }
9230 9230
9231 9231
9232 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { 9232 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
9233 ASSERT(!HasStackOverflow()); 9233 DCHECK(!HasStackOverflow());
9234 ASSERT(current_block() != NULL); 9234 DCHECK(current_block() != NULL);
9235 ASSERT(current_block()->HasPredecessor()); 9235 DCHECK(current_block()->HasPredecessor());
9236 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 9236 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
9237 int argument_count = expr->arguments()->length() + 1; // Plus constructor. 9237 int argument_count = expr->arguments()->length() + 1; // Plus constructor.
9238 Factory* factory = isolate()->factory(); 9238 Factory* factory = isolate()->factory();
9239 9239
9240 // The constructor function is on the stack in the unoptimized code 9240 // The constructor function is on the stack in the unoptimized code
9241 // during evaluation of the arguments. 9241 // during evaluation of the arguments.
9242 CHECK_ALIVE(VisitForValue(expr->expression())); 9242 CHECK_ALIVE(VisitForValue(expr->expression()));
9243 HValue* function = Top(); 9243 HValue* function = Top();
9244 CHECK_ALIVE(VisitExpressions(expr->arguments())); 9244 CHECK_ALIVE(VisitExpressions(expr->arguments()));
9245 9245
9246 if (FLAG_inline_construct && 9246 if (FLAG_inline_construct &&
9247 expr->IsMonomorphic() && 9247 expr->IsMonomorphic() &&
9248 IsAllocationInlineable(expr->target())) { 9248 IsAllocationInlineable(expr->target())) {
9249 Handle<JSFunction> constructor = expr->target(); 9249 Handle<JSFunction> constructor = expr->target();
9250 HValue* check = Add<HCheckValue>(function, constructor); 9250 HValue* check = Add<HCheckValue>(function, constructor);
9251 9251
9252 // Force completion of inobject slack tracking before generating 9252 // Force completion of inobject slack tracking before generating
9253 // allocation code to finalize instance size. 9253 // allocation code to finalize instance size.
9254 if (constructor->IsInobjectSlackTrackingInProgress()) { 9254 if (constructor->IsInobjectSlackTrackingInProgress()) {
9255 constructor->CompleteInobjectSlackTracking(); 9255 constructor->CompleteInobjectSlackTracking();
9256 } 9256 }
9257 9257
9258 // Calculate instance size from initial map of constructor. 9258 // Calculate instance size from initial map of constructor.
9259 ASSERT(constructor->has_initial_map()); 9259 DCHECK(constructor->has_initial_map());
9260 Handle<Map> initial_map(constructor->initial_map()); 9260 Handle<Map> initial_map(constructor->initial_map());
9261 int instance_size = initial_map->instance_size(); 9261 int instance_size = initial_map->instance_size();
9262 ASSERT(initial_map->InitialPropertiesLength() == 0); 9262 DCHECK(initial_map->InitialPropertiesLength() == 0);
9263 9263
9264 // Allocate an instance of the implicit receiver object. 9264 // Allocate an instance of the implicit receiver object.
9265 HValue* size_in_bytes = Add<HConstant>(instance_size); 9265 HValue* size_in_bytes = Add<HConstant>(instance_size);
9266 HAllocationMode allocation_mode; 9266 HAllocationMode allocation_mode;
9267 if (FLAG_pretenuring_call_new) { 9267 if (FLAG_pretenuring_call_new) {
9268 if (FLAG_allocation_site_pretenuring) { 9268 if (FLAG_allocation_site_pretenuring) {
9269 // Try to use pretenuring feedback. 9269 // Try to use pretenuring feedback.
9270 Handle<AllocationSite> allocation_site = expr->allocation_site(); 9270 Handle<AllocationSite> allocation_site = expr->allocation_site();
9271 allocation_mode = HAllocationMode(allocation_site); 9271 allocation_mode = HAllocationMode(allocation_site);
9272 // Take a dependency on allocation site. 9272 // Take a dependency on allocation site.
9273 AllocationSite::AddDependentCompilationInfo(allocation_site, 9273 AllocationSite::AddDependentCompilationInfo(allocation_site,
9274 AllocationSite::TENURING, 9274 AllocationSite::TENURING,
9275 top_info()); 9275 top_info());
9276 } 9276 }
9277 } 9277 }
9278 9278
9279 HAllocate* receiver = BuildAllocate( 9279 HAllocate* receiver = BuildAllocate(
9280 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode); 9280 size_in_bytes, HType::JSObject(), JS_OBJECT_TYPE, allocation_mode);
9281 receiver->set_known_initial_map(initial_map); 9281 receiver->set_known_initial_map(initial_map);
9282 9282
9283 // Initialize map and fields of the newly allocated object. 9283 // Initialize map and fields of the newly allocated object.
9284 { NoObservableSideEffectsScope no_effects(this); 9284 { NoObservableSideEffectsScope no_effects(this);
9285 ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE); 9285 DCHECK(initial_map->instance_type() == JS_OBJECT_TYPE);
9286 Add<HStoreNamedField>(receiver, 9286 Add<HStoreNamedField>(receiver,
9287 HObjectAccess::ForMapAndOffset(initial_map, JSObject::kMapOffset), 9287 HObjectAccess::ForMapAndOffset(initial_map, JSObject::kMapOffset),
9288 Add<HConstant>(initial_map)); 9288 Add<HConstant>(initial_map));
9289 HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array()); 9289 HValue* empty_fixed_array = Add<HConstant>(factory->empty_fixed_array());
9290 Add<HStoreNamedField>(receiver, 9290 Add<HStoreNamedField>(receiver,
9291 HObjectAccess::ForMapAndOffset(initial_map, 9291 HObjectAccess::ForMapAndOffset(initial_map,
9292 JSObject::kPropertiesOffset), 9292 JSObject::kPropertiesOffset),
9293 empty_fixed_array); 9293 empty_fixed_array);
9294 Add<HStoreNamedField>(receiver, 9294 Add<HStoreNamedField>(receiver,
9295 HObjectAccess::ForMapAndOffset(initial_map, 9295 HObjectAccess::ForMapAndOffset(initial_map,
9296 JSObject::kElementsOffset), 9296 JSObject::kElementsOffset),
9297 empty_fixed_array); 9297 empty_fixed_array);
9298 if (initial_map->inobject_properties() != 0) { 9298 if (initial_map->inobject_properties() != 0) {
9299 HConstant* undefined = graph()->GetConstantUndefined(); 9299 HConstant* undefined = graph()->GetConstantUndefined();
9300 for (int i = 0; i < initial_map->inobject_properties(); i++) { 9300 for (int i = 0; i < initial_map->inobject_properties(); i++) {
9301 int property_offset = initial_map->GetInObjectPropertyOffset(i); 9301 int property_offset = initial_map->GetInObjectPropertyOffset(i);
9302 Add<HStoreNamedField>(receiver, 9302 Add<HStoreNamedField>(receiver,
9303 HObjectAccess::ForMapAndOffset(initial_map, property_offset), 9303 HObjectAccess::ForMapAndOffset(initial_map, property_offset),
9304 undefined); 9304 undefined);
9305 } 9305 }
9306 } 9306 }
9307 } 9307 }
9308 9308
9309 // Replace the constructor function with a newly allocated receiver using 9309 // Replace the constructor function with a newly allocated receiver using
9310 // the index of the receiver from the top of the expression stack. 9310 // the index of the receiver from the top of the expression stack.
9311 const int receiver_index = argument_count - 1; 9311 const int receiver_index = argument_count - 1;
9312 ASSERT(environment()->ExpressionStackAt(receiver_index) == function); 9312 DCHECK(environment()->ExpressionStackAt(receiver_index) == function);
9313 environment()->SetExpressionStackAt(receiver_index, receiver); 9313 environment()->SetExpressionStackAt(receiver_index, receiver);
9314 9314
9315 if (TryInlineConstruct(expr, receiver)) { 9315 if (TryInlineConstruct(expr, receiver)) {
9316 // Inlining worked, add a dependency on the initial map to make sure that 9316 // Inlining worked, add a dependency on the initial map to make sure that
9317 // this code is deoptimized whenever the initial map of the constructor 9317 // this code is deoptimized whenever the initial map of the constructor
9318 // changes. 9318 // changes.
9319 Map::AddDependentCompilationInfo( 9319 Map::AddDependentCompilationInfo(
9320 initial_map, DependentCode::kInitialMapChangedGroup, top_info()); 9320 initial_map, DependentCode::kInitialMapChangedGroup, top_info());
9321 return; 9321 return;
9322 } 9322 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
9408 HObjectAccess::ForJSArrayBufferViewWeakNext(), 9408 HObjectAccess::ForJSArrayBufferViewWeakNext(),
9409 graph()->GetConstantUndefined()); 9409 graph()->GetConstantUndefined());
9410 } 9410 }
9411 } 9411 }
9412 9412
9413 9413
9414 void HOptimizedGraphBuilder::GenerateDataViewInitialize( 9414 void HOptimizedGraphBuilder::GenerateDataViewInitialize(
9415 CallRuntime* expr) { 9415 CallRuntime* expr) {
9416 ZoneList<Expression*>* arguments = expr->arguments(); 9416 ZoneList<Expression*>* arguments = expr->arguments();
9417 9417
9418 ASSERT(arguments->length()== 4); 9418 DCHECK(arguments->length()== 4);
9419 CHECK_ALIVE(VisitForValue(arguments->at(0))); 9419 CHECK_ALIVE(VisitForValue(arguments->at(0)));
9420 HValue* obj = Pop(); 9420 HValue* obj = Pop();
9421 9421
9422 CHECK_ALIVE(VisitForValue(arguments->at(1))); 9422 CHECK_ALIVE(VisitForValue(arguments->at(1)));
9423 HValue* buffer = Pop(); 9423 HValue* buffer = Pop();
9424 9424
9425 CHECK_ALIVE(VisitForValue(arguments->at(2))); 9425 CHECK_ALIVE(VisitForValue(arguments->at(2)));
9426 HValue* byte_offset = Pop(); 9426 HValue* byte_offset = Pop();
9427 9427
9428 CHECK_ALIVE(VisitForValue(arguments->at(3))); 9428 CHECK_ALIVE(VisitForValue(arguments->at(3)));
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
9552 void HOptimizedGraphBuilder::GenerateTypedArrayInitialize( 9552 void HOptimizedGraphBuilder::GenerateTypedArrayInitialize(
9553 CallRuntime* expr) { 9553 CallRuntime* expr) {
9554 ZoneList<Expression*>* arguments = expr->arguments(); 9554 ZoneList<Expression*>* arguments = expr->arguments();
9555 9555
9556 static const int kObjectArg = 0; 9556 static const int kObjectArg = 0;
9557 static const int kArrayIdArg = 1; 9557 static const int kArrayIdArg = 1;
9558 static const int kBufferArg = 2; 9558 static const int kBufferArg = 2;
9559 static const int kByteOffsetArg = 3; 9559 static const int kByteOffsetArg = 3;
9560 static const int kByteLengthArg = 4; 9560 static const int kByteLengthArg = 4;
9561 static const int kArgsLength = 5; 9561 static const int kArgsLength = 5;
9562 ASSERT(arguments->length() == kArgsLength); 9562 DCHECK(arguments->length() == kArgsLength);
9563 9563
9564 9564
9565 CHECK_ALIVE(VisitForValue(arguments->at(kObjectArg))); 9565 CHECK_ALIVE(VisitForValue(arguments->at(kObjectArg)));
9566 HValue* obj = Pop(); 9566 HValue* obj = Pop();
9567 9567
9568 if (arguments->at(kArrayIdArg)->IsLiteral()) { 9568 if (arguments->at(kArrayIdArg)->IsLiteral()) {
9569 // This should never happen in real use, but can happen when fuzzing. 9569 // This should never happen in real use, but can happen when fuzzing.
9570 // Just bail out. 9570 // Just bail out.
9571 Bailout(kNeedSmiLiteral); 9571 Bailout(kNeedSmiLiteral);
9572 return; 9572 return;
(...skipping 21 matching lines...) Expand all
9594 9594
9595 if (arguments->at(kByteOffsetArg)->IsLiteral() 9595 if (arguments->at(kByteOffsetArg)->IsLiteral()
9596 && Smi::FromInt(0) == 9596 && Smi::FromInt(0) ==
9597 *static_cast<Literal*>(arguments->at(kByteOffsetArg))->value()) { 9597 *static_cast<Literal*>(arguments->at(kByteOffsetArg))->value()) {
9598 byte_offset = Add<HConstant>(static_cast<int32_t>(0)); 9598 byte_offset = Add<HConstant>(static_cast<int32_t>(0));
9599 is_zero_byte_offset = true; 9599 is_zero_byte_offset = true;
9600 } else { 9600 } else {
9601 CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg))); 9601 CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg)));
9602 byte_offset = Pop(); 9602 byte_offset = Pop();
9603 is_zero_byte_offset = false; 9603 is_zero_byte_offset = false;
9604 ASSERT(buffer != NULL); 9604 DCHECK(buffer != NULL);
9605 } 9605 }
9606 9606
9607 CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg))); 9607 CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg)));
9608 HValue* byte_length = Pop(); 9608 HValue* byte_length = Pop();
9609 9609
9610 NoObservableSideEffectsScope scope(this); 9610 NoObservableSideEffectsScope scope(this);
9611 IfBuilder byte_offset_smi(this); 9611 IfBuilder byte_offset_smi(this);
9612 9612
9613 if (!is_zero_byte_offset) { 9613 if (!is_zero_byte_offset) {
9614 byte_offset_smi.If<HIsSmiAndBranch>(byte_offset); 9614 byte_offset_smi.If<HIsSmiAndBranch>(byte_offset);
(...skipping 27 matching lines...) Expand all
9642 length); 9642 length);
9643 9643
9644 HValue* elements; 9644 HValue* elements;
9645 if (buffer != NULL) { 9645 if (buffer != NULL) {
9646 elements = BuildAllocateExternalElements( 9646 elements = BuildAllocateExternalElements(
9647 array_type, is_zero_byte_offset, buffer, byte_offset, length); 9647 array_type, is_zero_byte_offset, buffer, byte_offset, length);
9648 Handle<Map> obj_map = TypedArrayMap( 9648 Handle<Map> obj_map = TypedArrayMap(
9649 isolate(), array_type, external_elements_kind); 9649 isolate(), array_type, external_elements_kind);
9650 AddStoreMapConstant(obj, obj_map); 9650 AddStoreMapConstant(obj, obj_map);
9651 } else { 9651 } else {
9652 ASSERT(is_zero_byte_offset); 9652 DCHECK(is_zero_byte_offset);
9653 elements = BuildAllocateFixedTypedArray( 9653 elements = BuildAllocateFixedTypedArray(
9654 array_type, element_size, fixed_elements_kind, 9654 array_type, element_size, fixed_elements_kind,
9655 byte_length, length); 9655 byte_length, length);
9656 } 9656 }
9657 Add<HStoreNamedField>( 9657 Add<HStoreNamedField>(
9658 obj, HObjectAccess::ForElementsPointer(), elements); 9658 obj, HObjectAccess::ForElementsPointer(), elements);
9659 } 9659 }
9660 9660
9661 if (!is_zero_byte_offset) { 9661 if (!is_zero_byte_offset) {
9662 byte_offset_smi.Else(); 9662 byte_offset_smi.Else();
9663 { // byte_offset is not Smi. 9663 { // byte_offset is not Smi.
9664 Push(obj); 9664 Push(obj);
9665 CHECK_ALIVE(VisitForValue(arguments->at(kArrayIdArg))); 9665 CHECK_ALIVE(VisitForValue(arguments->at(kArrayIdArg)));
9666 Push(buffer); 9666 Push(buffer);
9667 Push(byte_offset); 9667 Push(byte_offset);
9668 Push(byte_length); 9668 Push(byte_length);
9669 PushArgumentsFromEnvironment(kArgsLength); 9669 PushArgumentsFromEnvironment(kArgsLength);
9670 Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength); 9670 Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength);
9671 } 9671 }
9672 } 9672 }
9673 byte_offset_smi.End(); 9673 byte_offset_smi.End();
9674 } 9674 }
9675 9675
9676 9676
9677 void HOptimizedGraphBuilder::GenerateMaxSmi(CallRuntime* expr) { 9677 void HOptimizedGraphBuilder::GenerateMaxSmi(CallRuntime* expr) {
9678 ASSERT(expr->arguments()->length() == 0); 9678 DCHECK(expr->arguments()->length() == 0);
9679 HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue)); 9679 HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue));
9680 return ast_context()->ReturnInstruction(max_smi, expr->id()); 9680 return ast_context()->ReturnInstruction(max_smi, expr->id());
9681 } 9681 }
9682 9682
9683 9683
9684 void HOptimizedGraphBuilder::GenerateTypedArrayMaxSizeInHeap( 9684 void HOptimizedGraphBuilder::GenerateTypedArrayMaxSizeInHeap(
9685 CallRuntime* expr) { 9685 CallRuntime* expr) {
9686 ASSERT(expr->arguments()->length() == 0); 9686 DCHECK(expr->arguments()->length() == 0);
9687 HConstant* result = New<HConstant>(static_cast<int32_t>( 9687 HConstant* result = New<HConstant>(static_cast<int32_t>(
9688 FLAG_typed_array_max_size_in_heap)); 9688 FLAG_typed_array_max_size_in_heap));
9689 return ast_context()->ReturnInstruction(result, expr->id()); 9689 return ast_context()->ReturnInstruction(result, expr->id());
9690 } 9690 }
9691 9691
9692 9692
9693 void HOptimizedGraphBuilder::GenerateArrayBufferGetByteLength( 9693 void HOptimizedGraphBuilder::GenerateArrayBufferGetByteLength(
9694 CallRuntime* expr) { 9694 CallRuntime* expr) {
9695 ASSERT(expr->arguments()->length() == 1); 9695 DCHECK(expr->arguments()->length() == 1);
9696 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 9696 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
9697 HValue* buffer = Pop(); 9697 HValue* buffer = Pop();
9698 HInstruction* result = New<HLoadNamedField>( 9698 HInstruction* result = New<HLoadNamedField>(
9699 buffer, 9699 buffer,
9700 static_cast<HValue*>(NULL), 9700 static_cast<HValue*>(NULL),
9701 HObjectAccess::ForJSArrayBufferByteLength()); 9701 HObjectAccess::ForJSArrayBufferByteLength());
9702 return ast_context()->ReturnInstruction(result, expr->id()); 9702 return ast_context()->ReturnInstruction(result, expr->id());
9703 } 9703 }
9704 9704
9705 9705
9706 void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength( 9706 void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength(
9707 CallRuntime* expr) { 9707 CallRuntime* expr) {
9708 ASSERT(expr->arguments()->length() == 1); 9708 DCHECK(expr->arguments()->length() == 1);
9709 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 9709 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
9710 HValue* buffer = Pop(); 9710 HValue* buffer = Pop();
9711 HInstruction* result = New<HLoadNamedField>( 9711 HInstruction* result = New<HLoadNamedField>(
9712 buffer, 9712 buffer,
9713 static_cast<HValue*>(NULL), 9713 static_cast<HValue*>(NULL),
9714 HObjectAccess::ForJSArrayBufferViewByteLength()); 9714 HObjectAccess::ForJSArrayBufferViewByteLength());
9715 return ast_context()->ReturnInstruction(result, expr->id()); 9715 return ast_context()->ReturnInstruction(result, expr->id());
9716 } 9716 }
9717 9717
9718 9718
9719 void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset( 9719 void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset(
9720 CallRuntime* expr) { 9720 CallRuntime* expr) {
9721 ASSERT(expr->arguments()->length() == 1); 9721 DCHECK(expr->arguments()->length() == 1);
9722 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 9722 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
9723 HValue* buffer = Pop(); 9723 HValue* buffer = Pop();
9724 HInstruction* result = New<HLoadNamedField>( 9724 HInstruction* result = New<HLoadNamedField>(
9725 buffer, 9725 buffer,
9726 static_cast<HValue*>(NULL), 9726 static_cast<HValue*>(NULL),
9727 HObjectAccess::ForJSArrayBufferViewByteOffset()); 9727 HObjectAccess::ForJSArrayBufferViewByteOffset());
9728 return ast_context()->ReturnInstruction(result, expr->id()); 9728 return ast_context()->ReturnInstruction(result, expr->id());
9729 } 9729 }
9730 9730
9731 9731
9732 void HOptimizedGraphBuilder::GenerateTypedArrayGetLength( 9732 void HOptimizedGraphBuilder::GenerateTypedArrayGetLength(
9733 CallRuntime* expr) { 9733 CallRuntime* expr) {
9734 ASSERT(expr->arguments()->length() == 1); 9734 DCHECK(expr->arguments()->length() == 1);
9735 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); 9735 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
9736 HValue* buffer = Pop(); 9736 HValue* buffer = Pop();
9737 HInstruction* result = New<HLoadNamedField>( 9737 HInstruction* result = New<HLoadNamedField>(
9738 buffer, 9738 buffer,
9739 static_cast<HValue*>(NULL), 9739 static_cast<HValue*>(NULL),
9740 HObjectAccess::ForJSTypedArrayLength()); 9740 HObjectAccess::ForJSTypedArrayLength());
9741 return ast_context()->ReturnInstruction(result, expr->id()); 9741 return ast_context()->ReturnInstruction(result, expr->id());
9742 } 9742 }
9743 9743
9744 9744
9745 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { 9745 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
9746 ASSERT(!HasStackOverflow()); 9746 DCHECK(!HasStackOverflow());
9747 ASSERT(current_block() != NULL); 9747 DCHECK(current_block() != NULL);
9748 ASSERT(current_block()->HasPredecessor()); 9748 DCHECK(current_block()->HasPredecessor());
9749 if (expr->is_jsruntime()) { 9749 if (expr->is_jsruntime()) {
9750 return Bailout(kCallToAJavaScriptRuntimeFunction); 9750 return Bailout(kCallToAJavaScriptRuntimeFunction);
9751 } 9751 }
9752 9752
9753 const Runtime::Function* function = expr->function(); 9753 const Runtime::Function* function = expr->function();
9754 ASSERT(function != NULL); 9754 DCHECK(function != NULL);
9755 9755
9756 if (function->intrinsic_type == Runtime::INLINE || 9756 if (function->intrinsic_type == Runtime::INLINE ||
9757 function->intrinsic_type == Runtime::INLINE_OPTIMIZED) { 9757 function->intrinsic_type == Runtime::INLINE_OPTIMIZED) {
9758 ASSERT(expr->name()->length() > 0); 9758 DCHECK(expr->name()->length() > 0);
9759 ASSERT(expr->name()->Get(0) == '_'); 9759 DCHECK(expr->name()->Get(0) == '_');
9760 // Call to an inline function. 9760 // Call to an inline function.
9761 int lookup_index = static_cast<int>(function->function_id) - 9761 int lookup_index = static_cast<int>(function->function_id) -
9762 static_cast<int>(Runtime::kFirstInlineFunction); 9762 static_cast<int>(Runtime::kFirstInlineFunction);
9763 ASSERT(lookup_index >= 0); 9763 DCHECK(lookup_index >= 0);
9764 ASSERT(static_cast<size_t>(lookup_index) < 9764 DCHECK(static_cast<size_t>(lookup_index) <
9765 ARRAY_SIZE(kInlineFunctionGenerators)); 9765 ARRAY_SIZE(kInlineFunctionGenerators));
9766 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; 9766 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index];
9767 9767
9768 // Call the inline code generator using the pointer-to-member. 9768 // Call the inline code generator using the pointer-to-member.
9769 (this->*generator)(expr); 9769 (this->*generator)(expr);
9770 } else { 9770 } else {
9771 ASSERT(function->intrinsic_type == Runtime::RUNTIME); 9771 DCHECK(function->intrinsic_type == Runtime::RUNTIME);
9772 Handle<String> name = expr->name(); 9772 Handle<String> name = expr->name();
9773 int argument_count = expr->arguments()->length(); 9773 int argument_count = expr->arguments()->length();
9774 CHECK_ALIVE(VisitExpressions(expr->arguments())); 9774 CHECK_ALIVE(VisitExpressions(expr->arguments()));
9775 PushArgumentsFromEnvironment(argument_count); 9775 PushArgumentsFromEnvironment(argument_count);
9776 HCallRuntime* call = New<HCallRuntime>(name, function, 9776 HCallRuntime* call = New<HCallRuntime>(name, function,
9777 argument_count); 9777 argument_count);
9778 return ast_context()->ReturnInstruction(call, expr->id()); 9778 return ast_context()->ReturnInstruction(call, expr->id());
9779 } 9779 }
9780 } 9780 }
9781 9781
9782 9782
9783 void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 9783 void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
9784 ASSERT(!HasStackOverflow()); 9784 DCHECK(!HasStackOverflow());
9785 ASSERT(current_block() != NULL); 9785 DCHECK(current_block() != NULL);
9786 ASSERT(current_block()->HasPredecessor()); 9786 DCHECK(current_block()->HasPredecessor());
9787 switch (expr->op()) { 9787 switch (expr->op()) {
9788 case Token::DELETE: return VisitDelete(expr); 9788 case Token::DELETE: return VisitDelete(expr);
9789 case Token::VOID: return VisitVoid(expr); 9789 case Token::VOID: return VisitVoid(expr);
9790 case Token::TYPEOF: return VisitTypeof(expr); 9790 case Token::TYPEOF: return VisitTypeof(expr);
9791 case Token::NOT: return VisitNot(expr); 9791 case Token::NOT: return VisitNot(expr);
9792 default: UNREACHABLE(); 9792 default: UNREACHABLE();
9793 } 9793 }
9794 } 9794 }
9795 9795
9796 9796
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
9853 context->if_false(), 9853 context->if_false(),
9854 context->if_true()); 9854 context->if_true());
9855 return; 9855 return;
9856 } 9856 }
9857 9857
9858 if (ast_context()->IsEffect()) { 9858 if (ast_context()->IsEffect()) {
9859 VisitForEffect(expr->expression()); 9859 VisitForEffect(expr->expression());
9860 return; 9860 return;
9861 } 9861 }
9862 9862
9863 ASSERT(ast_context()->IsValue()); 9863 DCHECK(ast_context()->IsValue());
9864 HBasicBlock* materialize_false = graph()->CreateBasicBlock(); 9864 HBasicBlock* materialize_false = graph()->CreateBasicBlock();
9865 HBasicBlock* materialize_true = graph()->CreateBasicBlock(); 9865 HBasicBlock* materialize_true = graph()->CreateBasicBlock();
9866 CHECK_BAILOUT(VisitForControl(expr->expression(), 9866 CHECK_BAILOUT(VisitForControl(expr->expression(),
9867 materialize_false, 9867 materialize_false,
9868 materialize_true)); 9868 materialize_true));
9869 9869
9870 if (materialize_false->HasPredecessor()) { 9870 if (materialize_false->HasPredecessor()) {
9871 materialize_false->SetJoinId(expr->MaterializeFalseId()); 9871 materialize_false->SetJoinId(expr->MaterializeFalseId());
9872 set_current_block(materialize_false); 9872 set_current_block(materialize_false);
9873 Push(graph()->GetConstantFalse()); 9873 Push(graph()->GetConstantFalse());
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
9939 HValue* value) { 9939 HValue* value) {
9940 EffectContext for_effect(this); 9940 EffectContext for_effect(this);
9941 Push(object); 9941 Push(object);
9942 if (key != NULL) Push(key); 9942 if (key != NULL) Push(key);
9943 Push(value); 9943 Push(value);
9944 BuildStore(expr, prop, ast_id, return_id); 9944 BuildStore(expr, prop, ast_id, return_id);
9945 } 9945 }
9946 9946
9947 9947
9948 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { 9948 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
9949 ASSERT(!HasStackOverflow()); 9949 DCHECK(!HasStackOverflow());
9950 ASSERT(current_block() != NULL); 9950 DCHECK(current_block() != NULL);
9951 ASSERT(current_block()->HasPredecessor()); 9951 DCHECK(current_block()->HasPredecessor());
9952 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 9952 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
9953 Expression* target = expr->expression(); 9953 Expression* target = expr->expression();
9954 VariableProxy* proxy = target->AsVariableProxy(); 9954 VariableProxy* proxy = target->AsVariableProxy();
9955 Property* prop = target->AsProperty(); 9955 Property* prop = target->AsProperty();
9956 if (proxy == NULL && prop == NULL) { 9956 if (proxy == NULL && prop == NULL) {
9957 return Bailout(kInvalidLhsInCountOperation); 9957 return Bailout(kInvalidLhsInCountOperation);
9958 } 9958 }
9959 9959
9960 // Match the full code generator stack by simulating an extra stack 9960 // Match the full code generator stack by simulating an extra stack
9961 // element for postfix operations in a non-effect context. The return 9961 // element for postfix operations in a non-effect context. The return
9962 // value is ToNumber(input). 9962 // value is ToNumber(input).
9963 bool returns_original_input = 9963 bool returns_original_input =
9964 expr->is_postfix() && !ast_context()->IsEffect(); 9964 expr->is_postfix() && !ast_context()->IsEffect();
9965 HValue* input = NULL; // ToNumber(original_input). 9965 HValue* input = NULL; // ToNumber(original_input).
9966 HValue* after = NULL; // The result after incrementing or decrementing. 9966 HValue* after = NULL; // The result after incrementing or decrementing.
9967 9967
9968 if (proxy != NULL) { 9968 if (proxy != NULL) {
9969 Variable* var = proxy->var(); 9969 Variable* var = proxy->var();
9970 if (var->mode() == CONST_LEGACY) { 9970 if (var->mode() == CONST_LEGACY) {
9971 return Bailout(kUnsupportedCountOperationWithConst); 9971 return Bailout(kUnsupportedCountOperationWithConst);
9972 } 9972 }
9973 // Argument of the count operation is a variable, not a property. 9973 // Argument of the count operation is a variable, not a property.
9974 ASSERT(prop == NULL); 9974 DCHECK(prop == NULL);
9975 CHECK_ALIVE(VisitForValue(target)); 9975 CHECK_ALIVE(VisitForValue(target));
9976 9976
9977 after = BuildIncrement(returns_original_input, expr); 9977 after = BuildIncrement(returns_original_input, expr);
9978 input = returns_original_input ? Top() : Pop(); 9978 input = returns_original_input ? Top() : Pop();
9979 Push(after); 9979 Push(after);
9980 9980
9981 switch (var->location()) { 9981 switch (var->location()) {
9982 case Variable::UNALLOCATED: 9982 case Variable::UNALLOCATED:
9983 HandleGlobalVariableAssignment(var, 9983 HandleGlobalVariableAssignment(var,
9984 after, 9984 after,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
10019 10019
10020 case Variable::LOOKUP: 10020 case Variable::LOOKUP:
10021 return Bailout(kLookupVariableInCountOperation); 10021 return Bailout(kLookupVariableInCountOperation);
10022 } 10022 }
10023 10023
10024 Drop(returns_original_input ? 2 : 1); 10024 Drop(returns_original_input ? 2 : 1);
10025 return ast_context()->ReturnValue(expr->is_postfix() ? input : after); 10025 return ast_context()->ReturnValue(expr->is_postfix() ? input : after);
10026 } 10026 }
10027 10027
10028 // Argument of the count operation is a property. 10028 // Argument of the count operation is a property.
10029 ASSERT(prop != NULL); 10029 DCHECK(prop != NULL);
10030 if (returns_original_input) Push(graph()->GetConstantUndefined()); 10030 if (returns_original_input) Push(graph()->GetConstantUndefined());
10031 10031
10032 CHECK_ALIVE(VisitForValue(prop->obj())); 10032 CHECK_ALIVE(VisitForValue(prop->obj()));
10033 HValue* object = Top(); 10033 HValue* object = Top();
10034 10034
10035 HValue* key = NULL; 10035 HValue* key = NULL;
10036 if (!prop->key()->IsPropertyName() || prop->IsStringAccess()) { 10036 if (!prop->key()->IsPropertyName() || prop->IsStringAccess()) {
10037 CHECK_ALIVE(VisitForValue(prop->key())); 10037 CHECK_ALIVE(VisitForValue(prop->key()));
10038 key = Top(); 10038 key = Top();
10039 } 10039 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
10169 10169
10170 // Separate the number type from the rest. 10170 // Separate the number type from the rest.
10171 Type* expected_obj = 10171 Type* expected_obj =
10172 Type::Intersect(expected_type, Type::NonNumber(zone()), zone()); 10172 Type::Intersect(expected_type, Type::NonNumber(zone()), zone());
10173 Type* expected_number = 10173 Type* expected_number =
10174 Type::Intersect(expected_type, Type::Number(zone()), zone()); 10174 Type::Intersect(expected_type, Type::Number(zone()), zone());
10175 10175
10176 // We expect to get a number. 10176 // We expect to get a number.
10177 // (We need to check first, since Type::None->Is(Type::Any()) == true. 10177 // (We need to check first, since Type::None->Is(Type::Any()) == true.
10178 if (expected_obj->Is(Type::None())) { 10178 if (expected_obj->Is(Type::None())) {
10179 ASSERT(!expected_number->Is(Type::None(zone()))); 10179 DCHECK(!expected_number->Is(Type::None(zone())));
10180 return value; 10180 return value;
10181 } 10181 }
10182 10182
10183 if (expected_obj->Is(Type::Undefined(zone()))) { 10183 if (expected_obj->Is(Type::Undefined(zone()))) {
10184 // This is already done by HChange. 10184 // This is already done by HChange.
10185 *expected = Type::Union(expected_number, Type::Number(zone()), zone()); 10185 *expected = Type::Union(expected_number, Type::Number(zone()), zone());
10186 return value; 10186 return value;
10187 } 10187 }
10188 10188
10189 return value; 10189 return value;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
10272 left = BuildCheckString(left); 10272 left = BuildCheckString(left);
10273 } 10273 }
10274 10274
10275 // Validate type feedback for right argument. 10275 // Validate type feedback for right argument.
10276 if (right_type->Is(Type::String())) { 10276 if (right_type->Is(Type::String())) {
10277 right = BuildCheckString(right); 10277 right = BuildCheckString(right);
10278 } 10278 }
10279 10279
10280 // Convert left argument as necessary. 10280 // Convert left argument as necessary.
10281 if (left_type->Is(Type::Number())) { 10281 if (left_type->Is(Type::Number())) {
10282 ASSERT(right_type->Is(Type::String())); 10282 DCHECK(right_type->Is(Type::String()));
10283 left = BuildNumberToString(left, left_type); 10283 left = BuildNumberToString(left, left_type);
10284 } else if (!left_type->Is(Type::String())) { 10284 } else if (!left_type->Is(Type::String())) {
10285 ASSERT(right_type->Is(Type::String())); 10285 DCHECK(right_type->Is(Type::String()));
10286 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT); 10286 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_RIGHT);
10287 Add<HPushArguments>(left, right); 10287 Add<HPushArguments>(left, right);
10288 return AddUncasted<HInvokeFunction>(function, 2); 10288 return AddUncasted<HInvokeFunction>(function, 2);
10289 } 10289 }
10290 10290
10291 // Convert right argument as necessary. 10291 // Convert right argument as necessary.
10292 if (right_type->Is(Type::Number())) { 10292 if (right_type->Is(Type::Number())) {
10293 ASSERT(left_type->Is(Type::String())); 10293 DCHECK(left_type->Is(Type::String()));
10294 right = BuildNumberToString(right, right_type); 10294 right = BuildNumberToString(right, right_type);
10295 } else if (!right_type->Is(Type::String())) { 10295 } else if (!right_type->Is(Type::String())) {
10296 ASSERT(left_type->Is(Type::String())); 10296 DCHECK(left_type->Is(Type::String()));
10297 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT); 10297 HValue* function = AddLoadJSBuiltin(Builtins::STRING_ADD_LEFT);
10298 Add<HPushArguments>(left, right); 10298 Add<HPushArguments>(left, right);
10299 return AddUncasted<HInvokeFunction>(function, 2); 10299 return AddUncasted<HInvokeFunction>(function, 2);
10300 } 10300 }
10301 10301
10302 // Fast path for empty constant strings. 10302 // Fast path for empty constant strings.
10303 if (left->IsConstant() && 10303 if (left->IsConstant() &&
10304 HConstant::cast(left)->HasStringValue() && 10304 HConstant::cast(left)->HasStringValue() &&
10305 HConstant::cast(left)->StringValue()->length() == 0) { 10305 HConstant::cast(left)->StringValue()->length() == 0) {
10306 return right; 10306 return right;
10307 } 10307 }
10308 if (right->IsConstant() && 10308 if (right->IsConstant() &&
10309 HConstant::cast(right)->HasStringValue() && 10309 HConstant::cast(right)->HasStringValue() &&
10310 HConstant::cast(right)->StringValue()->length() == 0) { 10310 HConstant::cast(right)->StringValue()->length() == 0) {
10311 return left; 10311 return left;
10312 } 10312 }
10313 10313
10314 // Register the dependent code with the allocation site. 10314 // Register the dependent code with the allocation site.
10315 if (!allocation_mode.feedback_site().is_null()) { 10315 if (!allocation_mode.feedback_site().is_null()) {
10316 ASSERT(!graph()->info()->IsStub()); 10316 DCHECK(!graph()->info()->IsStub());
10317 Handle<AllocationSite> site(allocation_mode.feedback_site()); 10317 Handle<AllocationSite> site(allocation_mode.feedback_site());
10318 AllocationSite::AddDependentCompilationInfo( 10318 AllocationSite::AddDependentCompilationInfo(
10319 site, AllocationSite::TENURING, top_info()); 10319 site, AllocationSite::TENURING, top_info());
10320 } 10320 }
10321 10321
10322 // Inline the string addition into the stub when creating allocation 10322 // Inline the string addition into the stub when creating allocation
10323 // mementos to gather allocation site feedback, or if we can statically 10323 // mementos to gather allocation site feedback, or if we can statically
10324 // infer that we're going to create a cons string. 10324 // infer that we're going to create a cons string.
10325 if ((graph()->info()->IsStub() && 10325 if ((graph()->info()->IsStub() &&
10326 allocation_mode.CreateAllocationMementos()) || 10326 allocation_mode.CreateAllocationMementos()) ||
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
10447 static bool IsClassOfTest(CompareOperation* expr) { 10447 static bool IsClassOfTest(CompareOperation* expr) {
10448 if (expr->op() != Token::EQ_STRICT) return false; 10448 if (expr->op() != Token::EQ_STRICT) return false;
10449 CallRuntime* call = expr->left()->AsCallRuntime(); 10449 CallRuntime* call = expr->left()->AsCallRuntime();
10450 if (call == NULL) return false; 10450 if (call == NULL) return false;
10451 Literal* literal = expr->right()->AsLiteral(); 10451 Literal* literal = expr->right()->AsLiteral();
10452 if (literal == NULL) return false; 10452 if (literal == NULL) return false;
10453 if (!literal->value()->IsString()) return false; 10453 if (!literal->value()->IsString()) return false;
10454 if (!call->name()->IsOneByteEqualTo(STATIC_ASCII_VECTOR("_ClassOf"))) { 10454 if (!call->name()->IsOneByteEqualTo(STATIC_ASCII_VECTOR("_ClassOf"))) {
10455 return false; 10455 return false;
10456 } 10456 }
10457 ASSERT(call->arguments()->length() == 1); 10457 DCHECK(call->arguments()->length() == 1);
10458 return true; 10458 return true;
10459 } 10459 }
10460 10460
10461 10461
10462 void HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { 10462 void HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
10463 ASSERT(!HasStackOverflow()); 10463 DCHECK(!HasStackOverflow());
10464 ASSERT(current_block() != NULL); 10464 DCHECK(current_block() != NULL);
10465 ASSERT(current_block()->HasPredecessor()); 10465 DCHECK(current_block()->HasPredecessor());
10466 switch (expr->op()) { 10466 switch (expr->op()) {
10467 case Token::COMMA: 10467 case Token::COMMA:
10468 return VisitComma(expr); 10468 return VisitComma(expr);
10469 case Token::OR: 10469 case Token::OR:
10470 case Token::AND: 10470 case Token::AND:
10471 return VisitLogicalExpression(expr); 10471 return VisitLogicalExpression(expr);
10472 default: 10472 default:
10473 return VisitArithmeticExpression(expr); 10473 return VisitArithmeticExpression(expr);
10474 } 10474 }
10475 } 10475 }
(...skipping 26 matching lines...) Expand all
10502 // Translate right subexpression by visiting it in the same AST 10502 // Translate right subexpression by visiting it in the same AST
10503 // context as the entire expression. 10503 // context as the entire expression.
10504 if (eval_right->HasPredecessor()) { 10504 if (eval_right->HasPredecessor()) {
10505 eval_right->SetJoinId(expr->RightId()); 10505 eval_right->SetJoinId(expr->RightId());
10506 set_current_block(eval_right); 10506 set_current_block(eval_right);
10507 Visit(expr->right()); 10507 Visit(expr->right());
10508 } 10508 }
10509 10509
10510 } else if (ast_context()->IsValue()) { 10510 } else if (ast_context()->IsValue()) {
10511 CHECK_ALIVE(VisitForValue(expr->left())); 10511 CHECK_ALIVE(VisitForValue(expr->left()));
10512 ASSERT(current_block() != NULL); 10512 DCHECK(current_block() != NULL);
10513 HValue* left_value = Top(); 10513 HValue* left_value = Top();
10514 10514
10515 // Short-circuit left values that always evaluate to the same boolean value. 10515 // Short-circuit left values that always evaluate to the same boolean value.
10516 if (expr->left()->ToBooleanIsTrue() || expr->left()->ToBooleanIsFalse()) { 10516 if (expr->left()->ToBooleanIsTrue() || expr->left()->ToBooleanIsFalse()) {
10517 // l (evals true) && r -> r 10517 // l (evals true) && r -> r
10518 // l (evals true) || r -> l 10518 // l (evals true) || r -> l
10519 // l (evals false) && r -> l 10519 // l (evals false) && r -> l
10520 // l (evals false) || r -> r 10520 // l (evals false) || r -> r
10521 if (is_logical_and == expr->left()->ToBooleanIsTrue()) { 10521 if (is_logical_and == expr->left()->ToBooleanIsTrue()) {
10522 Drop(1); 10522 Drop(1);
(...skipping 14 matching lines...) Expand all
10537 set_current_block(eval_right); 10537 set_current_block(eval_right);
10538 Drop(1); // Value of the left subexpression. 10538 Drop(1); // Value of the left subexpression.
10539 CHECK_BAILOUT(VisitForValue(expr->right())); 10539 CHECK_BAILOUT(VisitForValue(expr->right()));
10540 10540
10541 HBasicBlock* join_block = 10541 HBasicBlock* join_block =
10542 CreateJoin(empty_block, current_block(), expr->id()); 10542 CreateJoin(empty_block, current_block(), expr->id());
10543 set_current_block(join_block); 10543 set_current_block(join_block);
10544 return ast_context()->ReturnValue(Pop()); 10544 return ast_context()->ReturnValue(Pop());
10545 10545
10546 } else { 10546 } else {
10547 ASSERT(ast_context()->IsEffect()); 10547 DCHECK(ast_context()->IsEffect());
10548 // In an effect context, we don't need the value of the left subexpression, 10548 // In an effect context, we don't need the value of the left subexpression,
10549 // only its control flow and side effects. We need an extra block to 10549 // only its control flow and side effects. We need an extra block to
10550 // maintain edge-split form. 10550 // maintain edge-split form.
10551 HBasicBlock* empty_block = graph()->CreateBasicBlock(); 10551 HBasicBlock* empty_block = graph()->CreateBasicBlock();
10552 HBasicBlock* right_block = graph()->CreateBasicBlock(); 10552 HBasicBlock* right_block = graph()->CreateBasicBlock();
10553 if (is_logical_and) { 10553 if (is_logical_and) {
10554 CHECK_BAILOUT(VisitForControl(expr->left(), right_block, empty_block)); 10554 CHECK_BAILOUT(VisitForControl(expr->left(), right_block, empty_block));
10555 } else { 10555 } else {
10556 CHECK_BAILOUT(VisitForControl(expr->left(), empty_block, right_block)); 10556 CHECK_BAILOUT(VisitForControl(expr->left(), empty_block, right_block));
10557 } 10557 }
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
10623 HValue* right) { 10623 HValue* right) {
10624 return op == Token::EQ_STRICT && 10624 return op == Token::EQ_STRICT &&
10625 ((left->IsConstant() && 10625 ((left->IsConstant() &&
10626 HConstant::cast(left)->handle(isolate)->IsBoolean()) || 10626 HConstant::cast(left)->handle(isolate)->IsBoolean()) ||
10627 (right->IsConstant() && 10627 (right->IsConstant() &&
10628 HConstant::cast(right)->handle(isolate)->IsBoolean())); 10628 HConstant::cast(right)->handle(isolate)->IsBoolean()));
10629 } 10629 }
10630 10630
10631 10631
10632 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 10632 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
10633 ASSERT(!HasStackOverflow()); 10633 DCHECK(!HasStackOverflow());
10634 ASSERT(current_block() != NULL); 10634 DCHECK(current_block() != NULL);
10635 ASSERT(current_block()->HasPredecessor()); 10635 DCHECK(current_block()->HasPredecessor());
10636 10636
10637 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 10637 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
10638 10638
10639 // Check for a few fast cases. The AST visiting behavior must be in sync 10639 // Check for a few fast cases. The AST visiting behavior must be in sync
10640 // with the full codegen: We don't push both left and right values onto 10640 // with the full codegen: We don't push both left and right values onto
10641 // the expression stack when one side is a special-case literal. 10641 // the expression stack when one side is a special-case literal.
10642 Expression* sub_expr = NULL; 10642 Expression* sub_expr = NULL;
10643 Handle<String> check; 10643 Handle<String> check;
10644 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 10644 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
10645 return HandleLiteralCompareTypeof(expr, sub_expr, check); 10645 return HandleLiteralCompareTypeof(expr, sub_expr, check);
10646 } 10646 }
10647 if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) { 10647 if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) {
10648 return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue); 10648 return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue);
10649 } 10649 }
10650 if (expr->IsLiteralCompareNull(&sub_expr)) { 10650 if (expr->IsLiteralCompareNull(&sub_expr)) {
10651 return HandleLiteralCompareNil(expr, sub_expr, kNullValue); 10651 return HandleLiteralCompareNil(expr, sub_expr, kNullValue);
10652 } 10652 }
10653 10653
10654 if (IsClassOfTest(expr)) { 10654 if (IsClassOfTest(expr)) {
10655 CallRuntime* call = expr->left()->AsCallRuntime(); 10655 CallRuntime* call = expr->left()->AsCallRuntime();
10656 ASSERT(call->arguments()->length() == 1); 10656 DCHECK(call->arguments()->length() == 1);
10657 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10657 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10658 HValue* value = Pop(); 10658 HValue* value = Pop();
10659 Literal* literal = expr->right()->AsLiteral(); 10659 Literal* literal = expr->right()->AsLiteral();
10660 Handle<String> rhs = Handle<String>::cast(literal->value()); 10660 Handle<String> rhs = Handle<String>::cast(literal->value());
10661 HClassOfTestAndBranch* instr = New<HClassOfTestAndBranch>(value, rhs); 10661 HClassOfTestAndBranch* instr = New<HClassOfTestAndBranch>(value, rhs);
10662 return ast_context()->ReturnControl(instr, expr->id()); 10662 return ast_context()->ReturnControl(instr, expr->id());
10663 } 10663 }
10664 10664
10665 Type* left_type = expr->left()->bounds().lower; 10665 Type* left_type = expr->left()->bounds().lower;
10666 Type* right_type = expr->right()->bounds().lower; 10666 Type* right_type = expr->right()->bounds().lower;
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
10857 } 10857 }
10858 return result; 10858 return result;
10859 } 10859 }
10860 } 10860 }
10861 } 10861 }
10862 10862
10863 10863
10864 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, 10864 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
10865 Expression* sub_expr, 10865 Expression* sub_expr,
10866 NilValue nil) { 10866 NilValue nil) {
10867 ASSERT(!HasStackOverflow()); 10867 DCHECK(!HasStackOverflow());
10868 ASSERT(current_block() != NULL); 10868 DCHECK(current_block() != NULL);
10869 ASSERT(current_block()->HasPredecessor()); 10869 DCHECK(current_block()->HasPredecessor());
10870 ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); 10870 DCHECK(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT);
10871 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); 10871 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
10872 CHECK_ALIVE(VisitForValue(sub_expr)); 10872 CHECK_ALIVE(VisitForValue(sub_expr));
10873 HValue* value = Pop(); 10873 HValue* value = Pop();
10874 if (expr->op() == Token::EQ_STRICT) { 10874 if (expr->op() == Token::EQ_STRICT) {
10875 HConstant* nil_constant = nil == kNullValue 10875 HConstant* nil_constant = nil == kNullValue
10876 ? graph()->GetConstantNull() 10876 ? graph()->GetConstantNull()
10877 : graph()->GetConstantUndefined(); 10877 : graph()->GetConstantUndefined();
10878 HCompareObjectEqAndBranch* instr = 10878 HCompareObjectEqAndBranch* instr =
10879 New<HCompareObjectEqAndBranch>(value, nil_constant); 10879 New<HCompareObjectEqAndBranch>(value, nil_constant);
10880 return ast_context()->ReturnControl(instr, expr->id()); 10880 return ast_context()->ReturnControl(instr, expr->id());
10881 } else { 10881 } else {
10882 ASSERT_EQ(Token::EQ, expr->op()); 10882 DCHECK_EQ(Token::EQ, expr->op());
10883 Type* type = expr->combined_type()->Is(Type::None()) 10883 Type* type = expr->combined_type()->Is(Type::None())
10884 ? Type::Any(zone()) : expr->combined_type(); 10884 ? Type::Any(zone()) : expr->combined_type();
10885 HIfContinuation continuation; 10885 HIfContinuation continuation;
10886 BuildCompareNil(value, type, &continuation); 10886 BuildCompareNil(value, type, &continuation);
10887 return ast_context()->ReturnContinuation(&continuation, expr->id()); 10887 return ast_context()->ReturnContinuation(&continuation, expr->id());
10888 } 10888 }
10889 } 10889 }
10890 10890
10891 10891
10892 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { 10892 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() {
10893 // If we share optimized code between different closures, the 10893 // If we share optimized code between different closures, the
10894 // this-function is not a constant, except inside an inlined body. 10894 // this-function is not a constant, except inside an inlined body.
10895 if (function_state()->outer() != NULL) { 10895 if (function_state()->outer() != NULL) {
10896 return New<HConstant>( 10896 return New<HConstant>(
10897 function_state()->compilation_info()->closure()); 10897 function_state()->compilation_info()->closure());
10898 } else { 10898 } else {
10899 return New<HThisFunction>(); 10899 return New<HThisFunction>();
10900 } 10900 }
10901 } 10901 }
10902 10902
10903 10903
10904 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( 10904 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral(
10905 Handle<JSObject> boilerplate_object, 10905 Handle<JSObject> boilerplate_object,
10906 AllocationSiteUsageContext* site_context) { 10906 AllocationSiteUsageContext* site_context) {
10907 NoObservableSideEffectsScope no_effects(this); 10907 NoObservableSideEffectsScope no_effects(this);
10908 InstanceType instance_type = boilerplate_object->map()->instance_type(); 10908 InstanceType instance_type = boilerplate_object->map()->instance_type();
10909 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); 10909 DCHECK(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE);
10910 10910
10911 HType type = instance_type == JS_ARRAY_TYPE 10911 HType type = instance_type == JS_ARRAY_TYPE
10912 ? HType::JSArray() : HType::JSObject(); 10912 ? HType::JSArray() : HType::JSObject();
10913 HValue* object_size_constant = Add<HConstant>( 10913 HValue* object_size_constant = Add<HConstant>(
10914 boilerplate_object->map()->instance_size()); 10914 boilerplate_object->map()->instance_size());
10915 10915
10916 PretenureFlag pretenure_flag = NOT_TENURED; 10916 PretenureFlag pretenure_flag = NOT_TENURED;
10917 if (FLAG_allocation_site_pretenuring) { 10917 if (FLAG_allocation_site_pretenuring) {
10918 pretenure_flag = site_context->current()->GetPretenureMode(); 10918 pretenure_flag = site_context->current()->GetPretenureMode();
10919 Handle<AllocationSite> site(site_context->current()); 10919 Handle<AllocationSite> site(site_context->current());
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
10974 BuildEmitInObjectProperties(boilerplate_object, object, site_context, 10974 BuildEmitInObjectProperties(boilerplate_object, object, site_context,
10975 pretenure_flag); 10975 pretenure_flag);
10976 } 10976 }
10977 return object; 10977 return object;
10978 } 10978 }
10979 10979
10980 10980
10981 void HOptimizedGraphBuilder::BuildEmitObjectHeader( 10981 void HOptimizedGraphBuilder::BuildEmitObjectHeader(
10982 Handle<JSObject> boilerplate_object, 10982 Handle<JSObject> boilerplate_object,
10983 HInstruction* object) { 10983 HInstruction* object) {
10984 ASSERT(boilerplate_object->properties()->length() == 0); 10984 DCHECK(boilerplate_object->properties()->length() == 0);
10985 10985
10986 Handle<Map> boilerplate_object_map(boilerplate_object->map()); 10986 Handle<Map> boilerplate_object_map(boilerplate_object->map());
10987 AddStoreMapConstant(object, boilerplate_object_map); 10987 AddStoreMapConstant(object, boilerplate_object_map);
10988 10988
10989 Handle<Object> properties_field = 10989 Handle<Object> properties_field =
10990 Handle<Object>(boilerplate_object->properties(), isolate()); 10990 Handle<Object>(boilerplate_object->properties(), isolate());
10991 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); 10991 DCHECK(*properties_field == isolate()->heap()->empty_fixed_array());
10992 HInstruction* properties = Add<HConstant>(properties_field); 10992 HInstruction* properties = Add<HConstant>(properties_field);
10993 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 10993 HObjectAccess access = HObjectAccess::ForPropertiesPointer();
10994 Add<HStoreNamedField>(object, access, properties); 10994 Add<HStoreNamedField>(object, access, properties);
10995 10995
10996 if (boilerplate_object->IsJSArray()) { 10996 if (boilerplate_object->IsJSArray()) {
10997 Handle<JSArray> boilerplate_array = 10997 Handle<JSArray> boilerplate_array =
10998 Handle<JSArray>::cast(boilerplate_object); 10998 Handle<JSArray>::cast(boilerplate_object);
10999 Handle<Object> length_field = 10999 Handle<Object> length_field =
11000 Handle<Object>(boilerplate_array->length(), isolate()); 11000 Handle<Object>(boilerplate_array->length(), isolate());
11001 HInstruction* length = Add<HConstant>(length_field); 11001 HInstruction* length = Add<HConstant>(length_field);
11002 11002
11003 ASSERT(boilerplate_array->length()->IsSmi()); 11003 DCHECK(boilerplate_array->length()->IsSmi());
11004 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength( 11004 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(
11005 boilerplate_array->GetElementsKind()), length); 11005 boilerplate_array->GetElementsKind()), length);
11006 } 11006 }
11007 } 11007 }
11008 11008
11009 11009
11010 void HOptimizedGraphBuilder::BuildInitElementsInObjectHeader( 11010 void HOptimizedGraphBuilder::BuildInitElementsInObjectHeader(
11011 Handle<JSObject> boilerplate_object, 11011 Handle<JSObject> boilerplate_object,
11012 HInstruction* object, 11012 HInstruction* object,
11013 HInstruction* object_elements) { 11013 HInstruction* object_elements) {
11014 ASSERT(boilerplate_object->properties()->length() == 0); 11014 DCHECK(boilerplate_object->properties()->length() == 0);
11015 if (object_elements == NULL) { 11015 if (object_elements == NULL) {
11016 Handle<Object> elements_field = 11016 Handle<Object> elements_field =
11017 Handle<Object>(boilerplate_object->elements(), isolate()); 11017 Handle<Object>(boilerplate_object->elements(), isolate());
11018 object_elements = Add<HConstant>(elements_field); 11018 object_elements = Add<HConstant>(elements_field);
11019 } 11019 }
11020 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(), 11020 Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
11021 object_elements); 11021 object_elements);
11022 } 11022 }
11023 11023
11024 11024
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
11088 } 11088 }
11089 11089
11090 Add<HStoreNamedField>(object, access, value_instruction); 11090 Add<HStoreNamedField>(object, access, value_instruction);
11091 } 11091 }
11092 } 11092 }
11093 11093
11094 int inobject_properties = boilerplate_object->map()->inobject_properties(); 11094 int inobject_properties = boilerplate_object->map()->inobject_properties();
11095 HInstruction* value_instruction = 11095 HInstruction* value_instruction =
11096 Add<HConstant>(isolate()->factory()->one_pointer_filler_map()); 11096 Add<HConstant>(isolate()->factory()->one_pointer_filler_map());
11097 for (int i = copied_fields; i < inobject_properties; i++) { 11097 for (int i = copied_fields; i < inobject_properties; i++) {
11098 ASSERT(boilerplate_object->IsJSObject()); 11098 DCHECK(boilerplate_object->IsJSObject());
11099 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i); 11099 int property_offset = boilerplate_object->GetInObjectPropertyOffset(i);
11100 HObjectAccess access = 11100 HObjectAccess access =
11101 HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset); 11101 HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset);
11102 Add<HStoreNamedField>(object, access, value_instruction); 11102 Add<HStoreNamedField>(object, access, value_instruction);
11103 } 11103 }
11104 } 11104 }
11105 11105
11106 11106
11107 void HOptimizedGraphBuilder::BuildEmitElements( 11107 void HOptimizedGraphBuilder::BuildEmitElements(
11108 Handle<JSObject> boilerplate_object, 11108 Handle<JSObject> boilerplate_object,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
11168 Add<HLoadKeyed>(boilerplate_elements, key_constant, 11168 Add<HLoadKeyed>(boilerplate_elements, key_constant,
11169 static_cast<HValue*>(NULL), kind, 11169 static_cast<HValue*>(NULL), kind,
11170 ALLOW_RETURN_HOLE); 11170 ALLOW_RETURN_HOLE);
11171 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind); 11171 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind);
11172 } 11172 }
11173 } 11173 }
11174 } 11174 }
11175 11175
11176 11176
11177 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { 11177 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) {
11178 ASSERT(!HasStackOverflow()); 11178 DCHECK(!HasStackOverflow());
11179 ASSERT(current_block() != NULL); 11179 DCHECK(current_block() != NULL);
11180 ASSERT(current_block()->HasPredecessor()); 11180 DCHECK(current_block()->HasPredecessor());
11181 HInstruction* instr = BuildThisFunction(); 11181 HInstruction* instr = BuildThisFunction();
11182 return ast_context()->ReturnInstruction(instr, expr->id()); 11182 return ast_context()->ReturnInstruction(instr, expr->id());
11183 } 11183 }
11184 11184
11185 11185
11186 void HOptimizedGraphBuilder::VisitDeclarations( 11186 void HOptimizedGraphBuilder::VisitDeclarations(
11187 ZoneList<Declaration*>* declarations) { 11187 ZoneList<Declaration*>* declarations) {
11188 ASSERT(globals_.is_empty()); 11188 DCHECK(globals_.is_empty());
11189 AstVisitor::VisitDeclarations(declarations); 11189 AstVisitor::VisitDeclarations(declarations);
11190 if (!globals_.is_empty()) { 11190 if (!globals_.is_empty()) {
11191 Handle<FixedArray> array = 11191 Handle<FixedArray> array =
11192 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); 11192 isolate()->factory()->NewFixedArray(globals_.length(), TENURED);
11193 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); 11193 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i));
11194 int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) | 11194 int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) |
11195 DeclareGlobalsNativeFlag::encode(current_info()->is_native()) | 11195 DeclareGlobalsNativeFlag::encode(current_info()->is_native()) |
11196 DeclareGlobalsStrictMode::encode(current_info()->strict_mode()); 11196 DeclareGlobalsStrictMode::encode(current_info()->strict_mode());
11197 Add<HDeclareGlobals>(array, flags); 11197 Add<HDeclareGlobals>(array, flags);
11198 globals_.Rewind(0); 11198 globals_.Rewind(0);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
11314 11314
11315 11315
11316 void HOptimizedGraphBuilder::VisitModuleStatement(ModuleStatement* stmt) { 11316 void HOptimizedGraphBuilder::VisitModuleStatement(ModuleStatement* stmt) {
11317 UNREACHABLE(); 11317 UNREACHABLE();
11318 } 11318 }
11319 11319
11320 11320
11321 // Generators for inline runtime functions. 11321 // Generators for inline runtime functions.
11322 // Support for types. 11322 // Support for types.
11323 void HOptimizedGraphBuilder::GenerateIsSmi(CallRuntime* call) { 11323 void HOptimizedGraphBuilder::GenerateIsSmi(CallRuntime* call) {
11324 ASSERT(call->arguments()->length() == 1); 11324 DCHECK(call->arguments()->length() == 1);
11325 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11325 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11326 HValue* value = Pop(); 11326 HValue* value = Pop();
11327 HIsSmiAndBranch* result = New<HIsSmiAndBranch>(value); 11327 HIsSmiAndBranch* result = New<HIsSmiAndBranch>(value);
11328 return ast_context()->ReturnControl(result, call->id()); 11328 return ast_context()->ReturnControl(result, call->id());
11329 } 11329 }
11330 11330
11331 11331
11332 void HOptimizedGraphBuilder::GenerateIsSpecObject(CallRuntime* call) { 11332 void HOptimizedGraphBuilder::GenerateIsSpecObject(CallRuntime* call) {
11333 ASSERT(call->arguments()->length() == 1); 11333 DCHECK(call->arguments()->length() == 1);
11334 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11334 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11335 HValue* value = Pop(); 11335 HValue* value = Pop();
11336 HHasInstanceTypeAndBranch* result = 11336 HHasInstanceTypeAndBranch* result =
11337 New<HHasInstanceTypeAndBranch>(value, 11337 New<HHasInstanceTypeAndBranch>(value,
11338 FIRST_SPEC_OBJECT_TYPE, 11338 FIRST_SPEC_OBJECT_TYPE,
11339 LAST_SPEC_OBJECT_TYPE); 11339 LAST_SPEC_OBJECT_TYPE);
11340 return ast_context()->ReturnControl(result, call->id()); 11340 return ast_context()->ReturnControl(result, call->id());
11341 } 11341 }
11342 11342
11343 11343
11344 void HOptimizedGraphBuilder::GenerateIsFunction(CallRuntime* call) { 11344 void HOptimizedGraphBuilder::GenerateIsFunction(CallRuntime* call) {
11345 ASSERT(call->arguments()->length() == 1); 11345 DCHECK(call->arguments()->length() == 1);
11346 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11346 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11347 HValue* value = Pop(); 11347 HValue* value = Pop();
11348 HHasInstanceTypeAndBranch* result = 11348 HHasInstanceTypeAndBranch* result =
11349 New<HHasInstanceTypeAndBranch>(value, JS_FUNCTION_TYPE); 11349 New<HHasInstanceTypeAndBranch>(value, JS_FUNCTION_TYPE);
11350 return ast_context()->ReturnControl(result, call->id()); 11350 return ast_context()->ReturnControl(result, call->id());
11351 } 11351 }
11352 11352
11353 11353
11354 void HOptimizedGraphBuilder::GenerateIsMinusZero(CallRuntime* call) { 11354 void HOptimizedGraphBuilder::GenerateIsMinusZero(CallRuntime* call) {
11355 ASSERT(call->arguments()->length() == 1); 11355 DCHECK(call->arguments()->length() == 1);
11356 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11356 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11357 HValue* value = Pop(); 11357 HValue* value = Pop();
11358 HCompareMinusZeroAndBranch* result = New<HCompareMinusZeroAndBranch>(value); 11358 HCompareMinusZeroAndBranch* result = New<HCompareMinusZeroAndBranch>(value);
11359 return ast_context()->ReturnControl(result, call->id()); 11359 return ast_context()->ReturnControl(result, call->id());
11360 } 11360 }
11361 11361
11362 11362
11363 void HOptimizedGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) { 11363 void HOptimizedGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) {
11364 ASSERT(call->arguments()->length() == 1); 11364 DCHECK(call->arguments()->length() == 1);
11365 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11365 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11366 HValue* value = Pop(); 11366 HValue* value = Pop();
11367 HHasCachedArrayIndexAndBranch* result = 11367 HHasCachedArrayIndexAndBranch* result =
11368 New<HHasCachedArrayIndexAndBranch>(value); 11368 New<HHasCachedArrayIndexAndBranch>(value);
11369 return ast_context()->ReturnControl(result, call->id()); 11369 return ast_context()->ReturnControl(result, call->id());
11370 } 11370 }
11371 11371
11372 11372
11373 void HOptimizedGraphBuilder::GenerateIsArray(CallRuntime* call) { 11373 void HOptimizedGraphBuilder::GenerateIsArray(CallRuntime* call) {
11374 ASSERT(call->arguments()->length() == 1); 11374 DCHECK(call->arguments()->length() == 1);
11375 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11375 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11376 HValue* value = Pop(); 11376 HValue* value = Pop();
11377 HHasInstanceTypeAndBranch* result = 11377 HHasInstanceTypeAndBranch* result =
11378 New<HHasInstanceTypeAndBranch>(value, JS_ARRAY_TYPE); 11378 New<HHasInstanceTypeAndBranch>(value, JS_ARRAY_TYPE);
11379 return ast_context()->ReturnControl(result, call->id()); 11379 return ast_context()->ReturnControl(result, call->id());
11380 } 11380 }
11381 11381
11382 11382
11383 void HOptimizedGraphBuilder::GenerateIsRegExp(CallRuntime* call) { 11383 void HOptimizedGraphBuilder::GenerateIsRegExp(CallRuntime* call) {
11384 ASSERT(call->arguments()->length() == 1); 11384 DCHECK(call->arguments()->length() == 1);
11385 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11385 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11386 HValue* value = Pop(); 11386 HValue* value = Pop();
11387 HHasInstanceTypeAndBranch* result = 11387 HHasInstanceTypeAndBranch* result =
11388 New<HHasInstanceTypeAndBranch>(value, JS_REGEXP_TYPE); 11388 New<HHasInstanceTypeAndBranch>(value, JS_REGEXP_TYPE);
11389 return ast_context()->ReturnControl(result, call->id()); 11389 return ast_context()->ReturnControl(result, call->id());
11390 } 11390 }
11391 11391
11392 11392
11393 void HOptimizedGraphBuilder::GenerateIsObject(CallRuntime* call) { 11393 void HOptimizedGraphBuilder::GenerateIsObject(CallRuntime* call) {
11394 ASSERT(call->arguments()->length() == 1); 11394 DCHECK(call->arguments()->length() == 1);
11395 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11395 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11396 HValue* value = Pop(); 11396 HValue* value = Pop();
11397 HIsObjectAndBranch* result = New<HIsObjectAndBranch>(value); 11397 HIsObjectAndBranch* result = New<HIsObjectAndBranch>(value);
11398 return ast_context()->ReturnControl(result, call->id()); 11398 return ast_context()->ReturnControl(result, call->id());
11399 } 11399 }
11400 11400
11401 11401
11402 void HOptimizedGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) { 11402 void HOptimizedGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) {
11403 return Bailout(kInlinedRuntimeFunctionIsNonNegativeSmi); 11403 return Bailout(kInlinedRuntimeFunctionIsNonNegativeSmi);
11404 } 11404 }
11405 11405
11406 11406
11407 void HOptimizedGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) { 11407 void HOptimizedGraphBuilder::GenerateIsUndetectableObject(CallRuntime* call) {
11408 ASSERT(call->arguments()->length() == 1); 11408 DCHECK(call->arguments()->length() == 1);
11409 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11409 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11410 HValue* value = Pop(); 11410 HValue* value = Pop();
11411 HIsUndetectableAndBranch* result = New<HIsUndetectableAndBranch>(value); 11411 HIsUndetectableAndBranch* result = New<HIsUndetectableAndBranch>(value);
11412 return ast_context()->ReturnControl(result, call->id()); 11412 return ast_context()->ReturnControl(result, call->id());
11413 } 11413 }
11414 11414
11415 11415
11416 void HOptimizedGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( 11416 void HOptimizedGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf(
11417 CallRuntime* call) { 11417 CallRuntime* call) {
11418 return Bailout(kInlinedRuntimeFunctionIsStringWrapperSafeForDefaultValueOf); 11418 return Bailout(kInlinedRuntimeFunctionIsStringWrapperSafeForDefaultValueOf);
11419 } 11419 }
11420 11420
11421 11421
11422 // Support for construct call checks. 11422 // Support for construct call checks.
11423 void HOptimizedGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { 11423 void HOptimizedGraphBuilder::GenerateIsConstructCall(CallRuntime* call) {
11424 ASSERT(call->arguments()->length() == 0); 11424 DCHECK(call->arguments()->length() == 0);
11425 if (function_state()->outer() != NULL) { 11425 if (function_state()->outer() != NULL) {
11426 // We are generating graph for inlined function. 11426 // We are generating graph for inlined function.
11427 HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN 11427 HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN
11428 ? graph()->GetConstantTrue() 11428 ? graph()->GetConstantTrue()
11429 : graph()->GetConstantFalse(); 11429 : graph()->GetConstantFalse();
11430 return ast_context()->ReturnValue(value); 11430 return ast_context()->ReturnValue(value);
11431 } else { 11431 } else {
11432 return ast_context()->ReturnControl(New<HIsConstructCallAndBranch>(), 11432 return ast_context()->ReturnControl(New<HIsConstructCallAndBranch>(),
11433 call->id()); 11433 call->id());
11434 } 11434 }
11435 } 11435 }
11436 11436
11437 11437
11438 // Support for arguments.length and arguments[?]. 11438 // Support for arguments.length and arguments[?].
11439 void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { 11439 void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) {
11440 ASSERT(call->arguments()->length() == 0); 11440 DCHECK(call->arguments()->length() == 0);
11441 HInstruction* result = NULL; 11441 HInstruction* result = NULL;
11442 if (function_state()->outer() == NULL) { 11442 if (function_state()->outer() == NULL) {
11443 HInstruction* elements = Add<HArgumentsElements>(false); 11443 HInstruction* elements = Add<HArgumentsElements>(false);
11444 result = New<HArgumentsLength>(elements); 11444 result = New<HArgumentsLength>(elements);
11445 } else { 11445 } else {
11446 // Number of arguments without receiver. 11446 // Number of arguments without receiver.
11447 int argument_count = environment()-> 11447 int argument_count = environment()->
11448 arguments_environment()->parameter_count() - 1; 11448 arguments_environment()->parameter_count() - 1;
11449 result = New<HConstant>(argument_count); 11449 result = New<HConstant>(argument_count);
11450 } 11450 }
11451 return ast_context()->ReturnInstruction(result, call->id()); 11451 return ast_context()->ReturnInstruction(result, call->id());
11452 } 11452 }
11453 11453
11454 11454
11455 void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { 11455 void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) {
11456 ASSERT(call->arguments()->length() == 1); 11456 DCHECK(call->arguments()->length() == 1);
11457 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11457 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11458 HValue* index = Pop(); 11458 HValue* index = Pop();
11459 HInstruction* result = NULL; 11459 HInstruction* result = NULL;
11460 if (function_state()->outer() == NULL) { 11460 if (function_state()->outer() == NULL) {
11461 HInstruction* elements = Add<HArgumentsElements>(false); 11461 HInstruction* elements = Add<HArgumentsElements>(false);
11462 HInstruction* length = Add<HArgumentsLength>(elements); 11462 HInstruction* length = Add<HArgumentsLength>(elements);
11463 HInstruction* checked_index = Add<HBoundsCheck>(index, length); 11463 HInstruction* checked_index = Add<HBoundsCheck>(index, length);
11464 result = New<HAccessArgumentsAt>(elements, length, checked_index); 11464 result = New<HAccessArgumentsAt>(elements, length, checked_index);
11465 } else { 11465 } else {
11466 EnsureArgumentsArePushedForAccess(); 11466 EnsureArgumentsArePushedForAccess();
(...skipping 12 matching lines...) Expand all
11479 11479
11480 // Support for accessing the class and value fields of an object. 11480 // Support for accessing the class and value fields of an object.
11481 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { 11481 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) {
11482 // The special form detected by IsClassOfTest is detected before we get here 11482 // The special form detected by IsClassOfTest is detected before we get here
11483 // and does not cause a bailout. 11483 // and does not cause a bailout.
11484 return Bailout(kInlinedRuntimeFunctionClassOf); 11484 return Bailout(kInlinedRuntimeFunctionClassOf);
11485 } 11485 }
11486 11486
11487 11487
11488 void HOptimizedGraphBuilder::GenerateValueOf(CallRuntime* call) { 11488 void HOptimizedGraphBuilder::GenerateValueOf(CallRuntime* call) {
11489 ASSERT(call->arguments()->length() == 1); 11489 DCHECK(call->arguments()->length() == 1);
11490 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11490 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11491 HValue* object = Pop(); 11491 HValue* object = Pop();
11492 11492
11493 IfBuilder if_objectisvalue(this); 11493 IfBuilder if_objectisvalue(this);
11494 HValue* objectisvalue = if_objectisvalue.If<HHasInstanceTypeAndBranch>( 11494 HValue* objectisvalue = if_objectisvalue.If<HHasInstanceTypeAndBranch>(
11495 object, JS_VALUE_TYPE); 11495 object, JS_VALUE_TYPE);
11496 if_objectisvalue.Then(); 11496 if_objectisvalue.Then();
11497 { 11497 {
11498 // Return the actual value. 11498 // Return the actual value.
11499 Push(Add<HLoadNamedField>( 11499 Push(Add<HLoadNamedField>(
11500 object, objectisvalue, 11500 object, objectisvalue,
11501 HObjectAccess::ForObservableJSObjectOffset( 11501 HObjectAccess::ForObservableJSObjectOffset(
11502 JSValue::kValueOffset))); 11502 JSValue::kValueOffset)));
11503 Add<HSimulate>(call->id(), FIXED_SIMULATE); 11503 Add<HSimulate>(call->id(), FIXED_SIMULATE);
11504 } 11504 }
11505 if_objectisvalue.Else(); 11505 if_objectisvalue.Else();
11506 { 11506 {
11507 // If the object is not a value return the object. 11507 // If the object is not a value return the object.
11508 Push(object); 11508 Push(object);
11509 Add<HSimulate>(call->id(), FIXED_SIMULATE); 11509 Add<HSimulate>(call->id(), FIXED_SIMULATE);
11510 } 11510 }
11511 if_objectisvalue.End(); 11511 if_objectisvalue.End();
11512 return ast_context()->ReturnValue(Pop()); 11512 return ast_context()->ReturnValue(Pop());
11513 } 11513 }
11514 11514
11515 11515
11516 void HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) { 11516 void HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) {
11517 ASSERT(call->arguments()->length() == 2); 11517 DCHECK(call->arguments()->length() == 2);
11518 ASSERT_NE(NULL, call->arguments()->at(1)->AsLiteral()); 11518 DCHECK_NE(NULL, call->arguments()->at(1)->AsLiteral());
11519 Smi* index = Smi::cast(*(call->arguments()->at(1)->AsLiteral()->value())); 11519 Smi* index = Smi::cast(*(call->arguments()->at(1)->AsLiteral()->value()));
11520 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11520 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11521 HValue* date = Pop(); 11521 HValue* date = Pop();
11522 HDateField* result = New<HDateField>(date, index); 11522 HDateField* result = New<HDateField>(date, index);
11523 return ast_context()->ReturnInstruction(result, call->id()); 11523 return ast_context()->ReturnInstruction(result, call->id());
11524 } 11524 }
11525 11525
11526 11526
11527 void HOptimizedGraphBuilder::GenerateOneByteSeqStringSetChar( 11527 void HOptimizedGraphBuilder::GenerateOneByteSeqStringSetChar(
11528 CallRuntime* call) { 11528 CallRuntime* call) {
11529 ASSERT(call->arguments()->length() == 3); 11529 DCHECK(call->arguments()->length() == 3);
11530 // We need to follow the evaluation order of full codegen. 11530 // We need to follow the evaluation order of full codegen.
11531 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11531 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
11532 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 11532 CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
11533 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11533 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11534 HValue* string = Pop(); 11534 HValue* string = Pop();
11535 HValue* value = Pop(); 11535 HValue* value = Pop();
11536 HValue* index = Pop(); 11536 HValue* index = Pop();
11537 Add<HSeqStringSetChar>(String::ONE_BYTE_ENCODING, string, 11537 Add<HSeqStringSetChar>(String::ONE_BYTE_ENCODING, string,
11538 index, value); 11538 index, value);
11539 Add<HSimulate>(call->id(), FIXED_SIMULATE); 11539 Add<HSimulate>(call->id(), FIXED_SIMULATE);
11540 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 11540 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
11541 } 11541 }
11542 11542
11543 11543
11544 void HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar( 11544 void HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar(
11545 CallRuntime* call) { 11545 CallRuntime* call) {
11546 ASSERT(call->arguments()->length() == 3); 11546 DCHECK(call->arguments()->length() == 3);
11547 // We need to follow the evaluation order of full codegen. 11547 // We need to follow the evaluation order of full codegen.
11548 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11548 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
11549 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 11549 CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
11550 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11550 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11551 HValue* string = Pop(); 11551 HValue* string = Pop();
11552 HValue* value = Pop(); 11552 HValue* value = Pop();
11553 HValue* index = Pop(); 11553 HValue* index = Pop();
11554 Add<HSeqStringSetChar>(String::TWO_BYTE_ENCODING, string, 11554 Add<HSeqStringSetChar>(String::TWO_BYTE_ENCODING, string,
11555 index, value); 11555 index, value);
11556 Add<HSimulate>(call->id(), FIXED_SIMULATE); 11556 Add<HSimulate>(call->id(), FIXED_SIMULATE);
11557 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 11557 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
11558 } 11558 }
11559 11559
11560 11560
11561 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { 11561 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) {
11562 ASSERT(call->arguments()->length() == 2); 11562 DCHECK(call->arguments()->length() == 2);
11563 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11563 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11564 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11564 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
11565 HValue* value = Pop(); 11565 HValue* value = Pop();
11566 HValue* object = Pop(); 11566 HValue* object = Pop();
11567 11567
11568 // Check if object is a JSValue. 11568 // Check if object is a JSValue.
11569 IfBuilder if_objectisvalue(this); 11569 IfBuilder if_objectisvalue(this);
11570 if_objectisvalue.If<HHasInstanceTypeAndBranch>(object, JS_VALUE_TYPE); 11570 if_objectisvalue.If<HHasInstanceTypeAndBranch>(object, JS_VALUE_TYPE);
11571 if_objectisvalue.Then(); 11571 if_objectisvalue.Then();
11572 { 11572 {
(...skipping 17 matching lines...) Expand all
11590 if_objectisvalue.End(); 11590 if_objectisvalue.End();
11591 if (!ast_context()->IsEffect()) { 11591 if (!ast_context()->IsEffect()) {
11592 Drop(1); 11592 Drop(1);
11593 } 11593 }
11594 return ast_context()->ReturnValue(value); 11594 return ast_context()->ReturnValue(value);
11595 } 11595 }
11596 11596
11597 11597
11598 // Fast support for charCodeAt(n). 11598 // Fast support for charCodeAt(n).
11599 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { 11599 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) {
11600 ASSERT(call->arguments()->length() == 2); 11600 DCHECK(call->arguments()->length() == 2);
11601 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11601 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11602 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11602 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
11603 HValue* index = Pop(); 11603 HValue* index = Pop();
11604 HValue* string = Pop(); 11604 HValue* string = Pop();
11605 HInstruction* result = BuildStringCharCodeAt(string, index); 11605 HInstruction* result = BuildStringCharCodeAt(string, index);
11606 return ast_context()->ReturnInstruction(result, call->id()); 11606 return ast_context()->ReturnInstruction(result, call->id());
11607 } 11607 }
11608 11608
11609 11609
11610 // Fast support for string.charAt(n) and string[n]. 11610 // Fast support for string.charAt(n) and string[n].
11611 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { 11611 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) {
11612 ASSERT(call->arguments()->length() == 1); 11612 DCHECK(call->arguments()->length() == 1);
11613 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11613 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11614 HValue* char_code = Pop(); 11614 HValue* char_code = Pop();
11615 HInstruction* result = NewUncasted<HStringCharFromCode>(char_code); 11615 HInstruction* result = NewUncasted<HStringCharFromCode>(char_code);
11616 return ast_context()->ReturnInstruction(result, call->id()); 11616 return ast_context()->ReturnInstruction(result, call->id());
11617 } 11617 }
11618 11618
11619 11619
11620 // Fast support for string.charAt(n) and string[n]. 11620 // Fast support for string.charAt(n) and string[n].
11621 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { 11621 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) {
11622 ASSERT(call->arguments()->length() == 2); 11622 DCHECK(call->arguments()->length() == 2);
11623 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11623 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11624 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11624 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
11625 HValue* index = Pop(); 11625 HValue* index = Pop();
11626 HValue* string = Pop(); 11626 HValue* string = Pop();
11627 HInstruction* char_code = BuildStringCharCodeAt(string, index); 11627 HInstruction* char_code = BuildStringCharCodeAt(string, index);
11628 AddInstruction(char_code); 11628 AddInstruction(char_code);
11629 HInstruction* result = NewUncasted<HStringCharFromCode>(char_code); 11629 HInstruction* result = NewUncasted<HStringCharFromCode>(char_code);
11630 return ast_context()->ReturnInstruction(result, call->id()); 11630 return ast_context()->ReturnInstruction(result, call->id());
11631 } 11631 }
11632 11632
11633 11633
11634 // Fast support for object equality testing. 11634 // Fast support for object equality testing.
11635 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { 11635 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) {
11636 ASSERT(call->arguments()->length() == 2); 11636 DCHECK(call->arguments()->length() == 2);
11637 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11637 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11638 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11638 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
11639 HValue* right = Pop(); 11639 HValue* right = Pop();
11640 HValue* left = Pop(); 11640 HValue* left = Pop();
11641 HCompareObjectEqAndBranch* result = 11641 HCompareObjectEqAndBranch* result =
11642 New<HCompareObjectEqAndBranch>(left, right); 11642 New<HCompareObjectEqAndBranch>(left, right);
11643 return ast_context()->ReturnControl(result, call->id()); 11643 return ast_context()->ReturnControl(result, call->id());
11644 } 11644 }
11645 11645
11646 11646
11647 // Fast support for StringAdd. 11647 // Fast support for StringAdd.
11648 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { 11648 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) {
11649 ASSERT_EQ(2, call->arguments()->length()); 11649 DCHECK_EQ(2, call->arguments()->length());
11650 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11650 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11651 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11651 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
11652 HValue* right = Pop(); 11652 HValue* right = Pop();
11653 HValue* left = Pop(); 11653 HValue* left = Pop();
11654 HInstruction* result = NewUncasted<HStringAdd>(left, right); 11654 HInstruction* result = NewUncasted<HStringAdd>(left, right);
11655 return ast_context()->ReturnInstruction(result, call->id()); 11655 return ast_context()->ReturnInstruction(result, call->id());
11656 } 11656 }
11657 11657
11658 11658
11659 // Fast support for SubString. 11659 // Fast support for SubString.
11660 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { 11660 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) {
11661 ASSERT_EQ(3, call->arguments()->length()); 11661 DCHECK_EQ(3, call->arguments()->length());
11662 CHECK_ALIVE(VisitExpressions(call->arguments())); 11662 CHECK_ALIVE(VisitExpressions(call->arguments()));
11663 PushArgumentsFromEnvironment(call->arguments()->length()); 11663 PushArgumentsFromEnvironment(call->arguments()->length());
11664 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3); 11664 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3);
11665 return ast_context()->ReturnInstruction(result, call->id()); 11665 return ast_context()->ReturnInstruction(result, call->id());
11666 } 11666 }
11667 11667
11668 11668
11669 // Fast support for StringCompare. 11669 // Fast support for StringCompare.
11670 void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) { 11670 void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) {
11671 ASSERT_EQ(2, call->arguments()->length()); 11671 DCHECK_EQ(2, call->arguments()->length());
11672 CHECK_ALIVE(VisitExpressions(call->arguments())); 11672 CHECK_ALIVE(VisitExpressions(call->arguments()));
11673 PushArgumentsFromEnvironment(call->arguments()->length()); 11673 PushArgumentsFromEnvironment(call->arguments()->length());
11674 HCallStub* result = New<HCallStub>(CodeStub::StringCompare, 2); 11674 HCallStub* result = New<HCallStub>(CodeStub::StringCompare, 2);
11675 return ast_context()->ReturnInstruction(result, call->id()); 11675 return ast_context()->ReturnInstruction(result, call->id());
11676 } 11676 }
11677 11677
11678 11678
11679 // Support for direct calls from JavaScript to native RegExp code. 11679 // Support for direct calls from JavaScript to native RegExp code.
11680 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { 11680 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) {
11681 ASSERT_EQ(4, call->arguments()->length()); 11681 DCHECK_EQ(4, call->arguments()->length());
11682 CHECK_ALIVE(VisitExpressions(call->arguments())); 11682 CHECK_ALIVE(VisitExpressions(call->arguments()));
11683 PushArgumentsFromEnvironment(call->arguments()->length()); 11683 PushArgumentsFromEnvironment(call->arguments()->length());
11684 HCallStub* result = New<HCallStub>(CodeStub::RegExpExec, 4); 11684 HCallStub* result = New<HCallStub>(CodeStub::RegExpExec, 4);
11685 return ast_context()->ReturnInstruction(result, call->id()); 11685 return ast_context()->ReturnInstruction(result, call->id());
11686 } 11686 }
11687 11687
11688 11688
11689 void HOptimizedGraphBuilder::GenerateDoubleLo(CallRuntime* call) { 11689 void HOptimizedGraphBuilder::GenerateDoubleLo(CallRuntime* call) {
11690 ASSERT_EQ(1, call->arguments()->length()); 11690 DCHECK_EQ(1, call->arguments()->length());
11691 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11691 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11692 HValue* value = Pop(); 11692 HValue* value = Pop();
11693 HInstruction* result = NewUncasted<HDoubleBits>(value, HDoubleBits::LOW); 11693 HInstruction* result = NewUncasted<HDoubleBits>(value, HDoubleBits::LOW);
11694 return ast_context()->ReturnInstruction(result, call->id()); 11694 return ast_context()->ReturnInstruction(result, call->id());
11695 } 11695 }
11696 11696
11697 11697
11698 void HOptimizedGraphBuilder::GenerateDoubleHi(CallRuntime* call) { 11698 void HOptimizedGraphBuilder::GenerateDoubleHi(CallRuntime* call) {
11699 ASSERT_EQ(1, call->arguments()->length()); 11699 DCHECK_EQ(1, call->arguments()->length());
11700 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11700 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11701 HValue* value = Pop(); 11701 HValue* value = Pop();
11702 HInstruction* result = NewUncasted<HDoubleBits>(value, HDoubleBits::HIGH); 11702 HInstruction* result = NewUncasted<HDoubleBits>(value, HDoubleBits::HIGH);
11703 return ast_context()->ReturnInstruction(result, call->id()); 11703 return ast_context()->ReturnInstruction(result, call->id());
11704 } 11704 }
11705 11705
11706 11706
11707 void HOptimizedGraphBuilder::GenerateConstructDouble(CallRuntime* call) { 11707 void HOptimizedGraphBuilder::GenerateConstructDouble(CallRuntime* call) {
11708 ASSERT_EQ(2, call->arguments()->length()); 11708 DCHECK_EQ(2, call->arguments()->length());
11709 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11709 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11710 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11710 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
11711 HValue* lo = Pop(); 11711 HValue* lo = Pop();
11712 HValue* hi = Pop(); 11712 HValue* hi = Pop();
11713 HInstruction* result = NewUncasted<HConstructDouble>(hi, lo); 11713 HInstruction* result = NewUncasted<HConstructDouble>(hi, lo);
11714 return ast_context()->ReturnInstruction(result, call->id()); 11714 return ast_context()->ReturnInstruction(result, call->id());
11715 } 11715 }
11716 11716
11717 11717
11718 // Construct a RegExp exec result with two in-object properties. 11718 // Construct a RegExp exec result with two in-object properties.
11719 void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { 11719 void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) {
11720 ASSERT_EQ(3, call->arguments()->length()); 11720 DCHECK_EQ(3, call->arguments()->length());
11721 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11721 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11722 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11722 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
11723 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 11723 CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
11724 HValue* input = Pop(); 11724 HValue* input = Pop();
11725 HValue* index = Pop(); 11725 HValue* index = Pop();
11726 HValue* length = Pop(); 11726 HValue* length = Pop();
11727 HValue* result = BuildRegExpConstructResult(length, index, input); 11727 HValue* result = BuildRegExpConstructResult(length, index, input);
11728 return ast_context()->ReturnValue(result); 11728 return ast_context()->ReturnValue(result);
11729 } 11729 }
11730 11730
11731 11731
11732 // Support for fast native caches. 11732 // Support for fast native caches.
11733 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) { 11733 void HOptimizedGraphBuilder::GenerateGetFromCache(CallRuntime* call) {
11734 return Bailout(kInlinedRuntimeFunctionGetFromCache); 11734 return Bailout(kInlinedRuntimeFunctionGetFromCache);
11735 } 11735 }
11736 11736
11737 11737
11738 // Fast support for number to string. 11738 // Fast support for number to string.
11739 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) { 11739 void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
11740 ASSERT_EQ(1, call->arguments()->length()); 11740 DCHECK_EQ(1, call->arguments()->length());
11741 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11741 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11742 HValue* number = Pop(); 11742 HValue* number = Pop();
11743 HValue* result = BuildNumberToString(number, Type::Any(zone())); 11743 HValue* result = BuildNumberToString(number, Type::Any(zone()));
11744 return ast_context()->ReturnValue(result); 11744 return ast_context()->ReturnValue(result);
11745 } 11745 }
11746 11746
11747 11747
11748 // Fast call for custom callbacks. 11748 // Fast call for custom callbacks.
11749 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { 11749 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) {
11750 // 1 ~ The function to call is not itself an argument to the call. 11750 // 1 ~ The function to call is not itself an argument to the call.
11751 int arg_count = call->arguments()->length() - 1; 11751 int arg_count = call->arguments()->length() - 1;
11752 ASSERT(arg_count >= 1); // There's always at least a receiver. 11752 DCHECK(arg_count >= 1); // There's always at least a receiver.
11753 11753
11754 CHECK_ALIVE(VisitExpressions(call->arguments())); 11754 CHECK_ALIVE(VisitExpressions(call->arguments()));
11755 // The function is the last argument 11755 // The function is the last argument
11756 HValue* function = Pop(); 11756 HValue* function = Pop();
11757 // Push the arguments to the stack 11757 // Push the arguments to the stack
11758 PushArgumentsFromEnvironment(arg_count); 11758 PushArgumentsFromEnvironment(arg_count);
11759 11759
11760 IfBuilder if_is_jsfunction(this); 11760 IfBuilder if_is_jsfunction(this);
11761 if_is_jsfunction.If<HHasInstanceTypeAndBranch>(function, JS_FUNCTION_TYPE); 11761 if_is_jsfunction.If<HHasInstanceTypeAndBranch>(function, JS_FUNCTION_TYPE);
11762 11762
(...skipping 23 matching lines...) Expand all
11786 // 'undefined' (as we do not have the call result anymore). 11786 // 'undefined' (as we do not have the call result anymore).
11787 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); 11787 return ast_context()->ReturnValue(graph()->GetConstantUndefined());
11788 } else { 11788 } else {
11789 return ast_context()->ReturnValue(Pop()); 11789 return ast_context()->ReturnValue(Pop());
11790 } 11790 }
11791 } 11791 }
11792 11792
11793 11793
11794 // Fast call to math functions. 11794 // Fast call to math functions.
11795 void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) { 11795 void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) {
11796 ASSERT_EQ(2, call->arguments()->length()); 11796 DCHECK_EQ(2, call->arguments()->length());
11797 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11797 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11798 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 11798 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
11799 HValue* right = Pop(); 11799 HValue* right = Pop();
11800 HValue* left = Pop(); 11800 HValue* left = Pop();
11801 HInstruction* result = NewUncasted<HPower>(left, right); 11801 HInstruction* result = NewUncasted<HPower>(left, right);
11802 return ast_context()->ReturnInstruction(result, call->id()); 11802 return ast_context()->ReturnInstruction(result, call->id());
11803 } 11803 }
11804 11804
11805 11805
11806 void HOptimizedGraphBuilder::GenerateMathLogRT(CallRuntime* call) { 11806 void HOptimizedGraphBuilder::GenerateMathLogRT(CallRuntime* call) {
11807 ASSERT(call->arguments()->length() == 1); 11807 DCHECK(call->arguments()->length() == 1);
11808 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11808 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11809 HValue* value = Pop(); 11809 HValue* value = Pop();
11810 HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathLog); 11810 HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathLog);
11811 return ast_context()->ReturnInstruction(result, call->id()); 11811 return ast_context()->ReturnInstruction(result, call->id());
11812 } 11812 }
11813 11813
11814 11814
11815 void HOptimizedGraphBuilder::GenerateMathSqrtRT(CallRuntime* call) { 11815 void HOptimizedGraphBuilder::GenerateMathSqrtRT(CallRuntime* call) {
11816 ASSERT(call->arguments()->length() == 1); 11816 DCHECK(call->arguments()->length() == 1);
11817 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11817 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11818 HValue* value = Pop(); 11818 HValue* value = Pop();
11819 HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathSqrt); 11819 HInstruction* result = NewUncasted<HUnaryMathOperation>(value, kMathSqrt);
11820 return ast_context()->ReturnInstruction(result, call->id()); 11820 return ast_context()->ReturnInstruction(result, call->id());
11821 } 11821 }
11822 11822
11823 11823
11824 void HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { 11824 void HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) {
11825 ASSERT(call->arguments()->length() == 1); 11825 DCHECK(call->arguments()->length() == 1);
11826 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 11826 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
11827 HValue* value = Pop(); 11827 HValue* value = Pop();
11828 HGetCachedArrayIndex* result = New<HGetCachedArrayIndex>(value); 11828 HGetCachedArrayIndex* result = New<HGetCachedArrayIndex>(value);
11829 return ast_context()->ReturnInstruction(result, call->id()); 11829 return ast_context()->ReturnInstruction(result, call->id());
11830 } 11830 }
11831 11831
11832 11832
11833 void HOptimizedGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) { 11833 void HOptimizedGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) {
11834 return Bailout(kInlinedRuntimeFunctionFastAsciiArrayJoin); 11834 return Bailout(kInlinedRuntimeFunctionFastAsciiArrayJoin);
11835 } 11835 }
(...skipping 11 matching lines...) Expand all
11847 11847
11848 11848
11849 void HOptimizedGraphBuilder::GenerateDebugBreakInOptimizedCode( 11849 void HOptimizedGraphBuilder::GenerateDebugBreakInOptimizedCode(
11850 CallRuntime* call) { 11850 CallRuntime* call) {
11851 Add<HDebugBreak>(); 11851 Add<HDebugBreak>();
11852 return ast_context()->ReturnValue(graph()->GetConstant0()); 11852 return ast_context()->ReturnValue(graph()->GetConstant0());
11853 } 11853 }
11854 11854
11855 11855
11856 void HOptimizedGraphBuilder::GenerateDebugIsActive(CallRuntime* call) { 11856 void HOptimizedGraphBuilder::GenerateDebugIsActive(CallRuntime* call) {
11857 ASSERT(call->arguments()->length() == 0); 11857 DCHECK(call->arguments()->length() == 0);
11858 HValue* ref = 11858 HValue* ref =
11859 Add<HConstant>(ExternalReference::debug_is_active_address(isolate())); 11859 Add<HConstant>(ExternalReference::debug_is_active_address(isolate()));
11860 HValue* value = Add<HLoadNamedField>( 11860 HValue* value = Add<HLoadNamedField>(
11861 ref, static_cast<HValue*>(NULL), HObjectAccess::ForExternalUInteger8()); 11861 ref, static_cast<HValue*>(NULL), HObjectAccess::ForExternalUInteger8());
11862 return ast_context()->ReturnValue(value); 11862 return ast_context()->ReturnValue(value);
11863 } 11863 }
11864 11864
11865 11865
11866 #undef CHECK_BAILOUT 11866 #undef CHECK_BAILOUT
11867 #undef CHECK_ALIVE 11867 #undef CHECK_ALIVE
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
11964 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy. 11964 if (other->outer_ != NULL) outer_ = other->outer_->Copy(); // Deep copy.
11965 entry_ = other->entry_; 11965 entry_ = other->entry_;
11966 pop_count_ = other->pop_count_; 11966 pop_count_ = other->pop_count_;
11967 push_count_ = other->push_count_; 11967 push_count_ = other->push_count_;
11968 specials_count_ = other->specials_count_; 11968 specials_count_ = other->specials_count_;
11969 ast_id_ = other->ast_id_; 11969 ast_id_ = other->ast_id_;
11970 } 11970 }
11971 11971
11972 11972
11973 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) { 11973 void HEnvironment::AddIncomingEdge(HBasicBlock* block, HEnvironment* other) {
11974 ASSERT(!block->IsLoopHeader()); 11974 DCHECK(!block->IsLoopHeader());
11975 ASSERT(values_.length() == other->values_.length()); 11975 DCHECK(values_.length() == other->values_.length());
11976 11976
11977 int length = values_.length(); 11977 int length = values_.length();
11978 for (int i = 0; i < length; ++i) { 11978 for (int i = 0; i < length; ++i) {
11979 HValue* value = values_[i]; 11979 HValue* value = values_[i];
11980 if (value != NULL && value->IsPhi() && value->block() == block) { 11980 if (value != NULL && value->IsPhi() && value->block() == block) {
11981 // There is already a phi for the i'th value. 11981 // There is already a phi for the i'th value.
11982 HPhi* phi = HPhi::cast(value); 11982 HPhi* phi = HPhi::cast(value);
11983 // Assert index is correct and that we haven't missed an incoming edge. 11983 // Assert index is correct and that we haven't missed an incoming edge.
11984 ASSERT(phi->merged_index() == i || !phi->HasMergedIndex()); 11984 DCHECK(phi->merged_index() == i || !phi->HasMergedIndex());
11985 ASSERT(phi->OperandCount() == block->predecessors()->length()); 11985 DCHECK(phi->OperandCount() == block->predecessors()->length());
11986 phi->AddInput(other->values_[i]); 11986 phi->AddInput(other->values_[i]);
11987 } else if (values_[i] != other->values_[i]) { 11987 } else if (values_[i] != other->values_[i]) {
11988 // There is a fresh value on the incoming edge, a phi is needed. 11988 // There is a fresh value on the incoming edge, a phi is needed.
11989 ASSERT(values_[i] != NULL && other->values_[i] != NULL); 11989 DCHECK(values_[i] != NULL && other->values_[i] != NULL);
11990 HPhi* phi = block->AddNewPhi(i); 11990 HPhi* phi = block->AddNewPhi(i);
11991 HValue* old_value = values_[i]; 11991 HValue* old_value = values_[i];
11992 for (int j = 0; j < block->predecessors()->length(); j++) { 11992 for (int j = 0; j < block->predecessors()->length(); j++) {
11993 phi->AddInput(old_value); 11993 phi->AddInput(old_value);
11994 } 11994 }
11995 phi->AddInput(other->values_[i]); 11995 phi->AddInput(other->values_[i]);
11996 this->values_[i] = phi; 11996 this->values_[i] = phi;
11997 } 11997 }
11998 } 11998 }
11999 } 11999 }
12000 12000
12001 12001
12002 void HEnvironment::Bind(int index, HValue* value) { 12002 void HEnvironment::Bind(int index, HValue* value) {
12003 ASSERT(value != NULL); 12003 DCHECK(value != NULL);
12004 assigned_variables_.Add(index, zone()); 12004 assigned_variables_.Add(index, zone());
12005 values_[index] = value; 12005 values_[index] = value;
12006 } 12006 }
12007 12007
12008 12008
12009 bool HEnvironment::HasExpressionAt(int index) const { 12009 bool HEnvironment::HasExpressionAt(int index) const {
12010 return index >= parameter_count_ + specials_count_ + local_count_; 12010 return index >= parameter_count_ + specials_count_ + local_count_;
12011 } 12011 }
12012 12012
12013 12013
12014 bool HEnvironment::ExpressionStackIsEmpty() const { 12014 bool HEnvironment::ExpressionStackIsEmpty() const {
12015 ASSERT(length() >= first_expression_index()); 12015 DCHECK(length() >= first_expression_index());
12016 return length() == first_expression_index(); 12016 return length() == first_expression_index();
12017 } 12017 }
12018 12018
12019 12019
12020 void HEnvironment::SetExpressionStackAt(int index_from_top, HValue* value) { 12020 void HEnvironment::SetExpressionStackAt(int index_from_top, HValue* value) {
12021 int count = index_from_top + 1; 12021 int count = index_from_top + 1;
12022 int index = values_.length() - count; 12022 int index = values_.length() - count;
12023 ASSERT(HasExpressionAt(index)); 12023 DCHECK(HasExpressionAt(index));
12024 // The push count must include at least the element in question or else 12024 // The push count must include at least the element in question or else
12025 // the new value will not be included in this environment's history. 12025 // the new value will not be included in this environment's history.
12026 if (push_count_ < count) { 12026 if (push_count_ < count) {
12027 // This is the same effect as popping then re-pushing 'count' elements. 12027 // This is the same effect as popping then re-pushing 'count' elements.
12028 pop_count_ += (count - push_count_); 12028 pop_count_ += (count - push_count_);
12029 push_count_ = count; 12029 push_count_ = count;
12030 } 12030 }
12031 values_[index] = value; 12031 values_[index] = value;
12032 } 12032 }
12033 12033
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
12077 return new_env; 12077 return new_env;
12078 } 12078 }
12079 12079
12080 12080
12081 HEnvironment* HEnvironment::CopyForInlining( 12081 HEnvironment* HEnvironment::CopyForInlining(
12082 Handle<JSFunction> target, 12082 Handle<JSFunction> target,
12083 int arguments, 12083 int arguments,
12084 FunctionLiteral* function, 12084 FunctionLiteral* function,
12085 HConstant* undefined, 12085 HConstant* undefined,
12086 InliningKind inlining_kind) const { 12086 InliningKind inlining_kind) const {
12087 ASSERT(frame_type() == JS_FUNCTION); 12087 DCHECK(frame_type() == JS_FUNCTION);
12088 12088
12089 // Outer environment is a copy of this one without the arguments. 12089 // Outer environment is a copy of this one without the arguments.
12090 int arity = function->scope()->num_parameters(); 12090 int arity = function->scope()->num_parameters();
12091 12091
12092 HEnvironment* outer = Copy(); 12092 HEnvironment* outer = Copy();
12093 outer->Drop(arguments + 1); // Including receiver. 12093 outer->Drop(arguments + 1); // Including receiver.
12094 outer->ClearHistory(); 12094 outer->ClearHistory();
12095 12095
12096 if (inlining_kind == CONSTRUCT_CALL_RETURN) { 12096 if (inlining_kind == CONSTRUCT_CALL_RETURN) {
12097 // Create artificial constructor stub environment. The receiver should 12097 // Create artificial constructor stub environment. The receiver should
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
12165 CodeStub::Major major_key = info->code_stub()->MajorKey(); 12165 CodeStub::Major major_key = info->code_stub()->MajorKey();
12166 PrintStringProperty("name", CodeStub::MajorName(major_key, false)); 12166 PrintStringProperty("name", CodeStub::MajorName(major_key, false));
12167 PrintStringProperty("method", "stub"); 12167 PrintStringProperty("method", "stub");
12168 } 12168 }
12169 PrintLongProperty("date", 12169 PrintLongProperty("date",
12170 static_cast<int64_t>(base::OS::TimeCurrentMillis())); 12170 static_cast<int64_t>(base::OS::TimeCurrentMillis()));
12171 } 12171 }
12172 12172
12173 12173
12174 void HTracer::TraceLithium(const char* name, LChunk* chunk) { 12174 void HTracer::TraceLithium(const char* name, LChunk* chunk) {
12175 ASSERT(!chunk->isolate()->concurrent_recompilation_enabled()); 12175 DCHECK(!chunk->isolate()->concurrent_recompilation_enabled());
12176 AllowHandleDereference allow_deref; 12176 AllowHandleDereference allow_deref;
12177 AllowDeferredHandleDereference allow_deferred_deref; 12177 AllowDeferredHandleDereference allow_deferred_deref;
12178 Trace(name, chunk->graph(), chunk); 12178 Trace(name, chunk->graph(), chunk);
12179 } 12179 }
12180 12180
12181 12181
12182 void HTracer::TraceHydrogen(const char* name, HGraph* graph) { 12182 void HTracer::TraceHydrogen(const char* name, HGraph* graph) {
12183 ASSERT(!graph->isolate()->concurrent_recompilation_enabled()); 12183 DCHECK(!graph->isolate()->concurrent_recompilation_enabled());
12184 AllowHandleDereference allow_deref; 12184 AllowHandleDereference allow_deref;
12185 AllowDeferredHandleDereference allow_deferred_deref; 12185 AllowDeferredHandleDereference allow_deferred_deref;
12186 Trace(name, graph, NULL); 12186 Trace(name, graph, NULL);
12187 } 12187 }
12188 12188
12189 12189
12190 void HTracer::Trace(const char* name, HGraph* graph, LChunk* chunk) { 12190 void HTracer::Trace(const char* name, HGraph* graph, LChunk* chunk) {
12191 Tag tag(this, "cfg"); 12191 Tag tag(this, "cfg");
12192 PrintStringProperty("name", name); 12192 PrintStringProperty("name", name);
12193 const ZoneList<HBasicBlock*>* blocks = graph->blocks(); 12193 const ZoneList<HBasicBlock*>* blocks = graph->blocks();
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
12341 if (range != NULL && !range->IsEmpty()) { 12341 if (range != NULL && !range->IsEmpty()) {
12342 PrintIndent(); 12342 PrintIndent();
12343 trace_.Add("%d %s", range->id(), type); 12343 trace_.Add("%d %s", range->id(), type);
12344 if (range->HasRegisterAssigned()) { 12344 if (range->HasRegisterAssigned()) {
12345 LOperand* op = range->CreateAssignedOperand(zone); 12345 LOperand* op = range->CreateAssignedOperand(zone);
12346 int assigned_reg = op->index(); 12346 int assigned_reg = op->index();
12347 if (op->IsDoubleRegister()) { 12347 if (op->IsDoubleRegister()) {
12348 trace_.Add(" \"%s\"", 12348 trace_.Add(" \"%s\"",
12349 DoubleRegister::AllocationIndexToString(assigned_reg)); 12349 DoubleRegister::AllocationIndexToString(assigned_reg));
12350 } else { 12350 } else {
12351 ASSERT(op->IsRegister()); 12351 DCHECK(op->IsRegister());
12352 trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg)); 12352 trace_.Add(" \"%s\"", Register::AllocationIndexToString(assigned_reg));
12353 } 12353 }
12354 } else if (range->IsSpilled()) { 12354 } else if (range->IsSpilled()) {
12355 LOperand* op = range->TopLevel()->GetSpillOperand(); 12355 LOperand* op = range->TopLevel()->GetSpillOperand();
12356 if (op->IsDoubleStackSlot()) { 12356 if (op->IsDoubleStackSlot()) {
12357 trace_.Add(" \"double_stack:%d\"", op->index()); 12357 trace_.Add(" \"double_stack:%d\"", op->index());
12358 } else { 12358 } else {
12359 ASSERT(op->IsStackSlot()); 12359 DCHECK(op->IsStackSlot());
12360 trace_.Add(" \"stack:%d\"", op->index()); 12360 trace_.Add(" \"stack:%d\"", op->index());
12361 } 12361 }
12362 } 12362 }
12363 int parent_index = -1; 12363 int parent_index = -1;
12364 if (range->IsChild()) { 12364 if (range->IsChild()) {
12365 parent_index = range->parent()->id(); 12365 parent_index = range->parent()->id();
12366 } else { 12366 } else {
12367 parent_index = range->id(); 12367 parent_index = range->id();
12368 } 12368 }
12369 LOperand* op = range->FirstHint(); 12369 LOperand* op = range->FirstHint();
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
12481 if (ShouldProduceTraceOutput()) { 12481 if (ShouldProduceTraceOutput()) {
12482 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12482 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12483 } 12483 }
12484 12484
12485 #ifdef DEBUG 12485 #ifdef DEBUG
12486 graph_->Verify(false); // No full verify. 12486 graph_->Verify(false); // No full verify.
12487 #endif 12487 #endif
12488 } 12488 }
12489 12489
12490 } } // namespace v8::internal 12490 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-bce.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698