| OLD | NEW |
| 1 // Copyright 2007-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 } | 372 } |
| 373 | 373 |
| 374 | 374 |
| 375 void CodeGenerator::GenerateFastCaseSwitchStatement(SwitchStatement* node, | 375 void CodeGenerator::GenerateFastCaseSwitchStatement(SwitchStatement* node, |
| 376 int min_index, | 376 int min_index, |
| 377 int range, | 377 int range, |
| 378 int default_index) { | 378 int default_index) { |
| 379 ZoneList<CaseClause*>* cases = node->cases(); | 379 ZoneList<CaseClause*>* cases = node->cases(); |
| 380 int length = cases->length(); | 380 int length = cases->length(); |
| 381 | 381 |
| 382 // JumpTarget pointer per number in range. | 382 // Label pointer per number in range. |
| 383 SmartPointer<JumpTarget*> case_targets(NewArray<JumpTarget*>(range)); | 383 SmartPointer<Label*> case_targets(NewArray<Label*>(range)); |
| 384 | 384 |
| 385 // JumpTarget per switch case. | 385 // Label per switch case. |
| 386 SmartPointer<JumpTarget> case_labels(NewArray<JumpTarget>(length)); | 386 SmartPointer<Label> case_labels(NewArray<Label>(length)); |
| 387 for (int i = 0; i < length; i++) { | |
| 388 case_labels[i].Initialize(this); | |
| 389 } | |
| 390 | 387 |
| 391 JumpTarget* fail_label = default_index >= 0 ? &(case_labels[default_index]) | 388 Label* fail_label = |
| 392 : node->break_target(); | 389 default_index >= 0 ? &(case_labels[default_index]) : NULL; |
| 393 | 390 |
| 394 // Populate array of label pointers for each number in the range. | 391 // Populate array of label pointers for each number in the range. |
| 395 // Initally put the failure label everywhere. | 392 // Initally put the failure label everywhere. |
| 396 for (int i = 0; i < range; i++) { | 393 for (int i = 0; i < range; i++) { |
| 397 case_targets[i] = fail_label; | 394 case_targets[i] = fail_label; |
| 398 } | 395 } |
| 399 | 396 |
| 400 // Overwrite with label of a case for the number value of that case. | 397 // Overwrite with label of a case for the number value of that case. |
| 401 // (In reverse order, so that if the same label occurs twice, the | 398 // (In reverse order, so that if the same label occurs twice, the |
| 402 // first one wins). | 399 // first one wins). |
| 403 for (int i = length-1; i >= 0 ; i--) { | 400 for (int i = length - 1; i >= 0 ; i--) { |
| 404 CaseClause* clause = cases->at(i); | 401 CaseClause* clause = cases->at(i); |
| 405 if (!clause->is_default()) { | 402 if (!clause->is_default()) { |
| 406 Object* label_value = *(clause->label()->AsLiteral()->handle()); | 403 Object* label_value = *(clause->label()->AsLiteral()->handle()); |
| 407 int case_value = Smi::cast(label_value)->value(); | 404 int case_value = Smi::cast(label_value)->value(); |
| 408 case_targets[case_value - min_index] = &(case_labels[i]); | 405 case_targets[case_value - min_index] = &(case_labels[i]); |
| 409 } | 406 } |
| 410 } | 407 } |
| 411 | 408 |
| 412 GenerateFastCaseSwitchJumpTable(node, | 409 GenerateFastCaseSwitchJumpTable(node, |
| 413 min_index, | 410 min_index, |
| 414 range, | 411 range, |
| 415 fail_label, | 412 fail_label, |
| 416 Vector<JumpTarget*>(*case_targets, range), | 413 Vector<Label*>(*case_targets, range), |
| 417 Vector<JumpTarget>(*case_labels, length)); | 414 Vector<Label>(*case_labels, length)); |
| 418 } | 415 } |
| 419 | 416 |
| 420 | 417 |
| 421 void CodeGenerator::GenerateFastCaseSwitchCases( | 418 void CodeGenerator::GenerateFastCaseSwitchCases( |
| 422 SwitchStatement* node, | 419 SwitchStatement* node, |
| 423 Vector<JumpTarget> case_labels, | 420 Vector<Label> case_labels, |
| 424 JumpTarget* table_start) { | 421 VirtualFrame* start_frame) { |
| 425 ZoneList<CaseClause*>* cases = node->cases(); | 422 ZoneList<CaseClause*>* cases = node->cases(); |
| 426 int length = cases->length(); | 423 int length = cases->length(); |
| 427 | 424 |
| 428 for (int i = 0; i < length; i++) { | 425 for (int i = 0; i < length; i++) { |
| 429 Comment cmnt(masm(), "[ Case clause"); | 426 Comment cmnt(masm(), "[ Case clause"); |
| 430 case_labels[i].Bind(); | 427 masm()->bind(&case_labels[i]); |
| 431 VisitStatements(cases->at(i)->statements()); | 428 VisitStatements(cases->at(i)->statements()); |
| 432 | 429 |
| 433 // All of the labels match the same expected frame as the table start. | 430 // If control flow did not fall off the end of the case statement, |
| 434 // If control flow cannot fall off the end of the case statement, we | 431 // we restore the expected frame for the next iteration (or exit |
| 435 // pick up the expected frame from the table start. Otherwise we have | 432 // of the loop). Otherwise we have to generate merge code to |
| 436 // to generate merge code to match the next label. | 433 // expectation at the next case. |
| 437 if (frame_ == NULL) { | 434 if (frame_ == NULL) { |
| 438 frame_ = new VirtualFrame(table_start->expected_frame()); | 435 frame_ = new VirtualFrame(start_frame); |
| 439 } else { | 436 } else { |
| 440 frame_->MergeTo(table_start->expected_frame()); | 437 frame_->MergeTo(start_frame); |
| 441 } | 438 } |
| 442 } | 439 } |
| 443 | |
| 444 node->break_target()->Bind(); | |
| 445 } | 440 } |
| 446 | 441 |
| 447 | 442 |
| 448 bool CodeGenerator::TryGenerateFastCaseSwitchStatement(SwitchStatement* node) { | 443 bool CodeGenerator::TryGenerateFastCaseSwitchStatement(SwitchStatement* node) { |
| 449 ZoneList<CaseClause*>* cases = node->cases(); | 444 ZoneList<CaseClause*>* cases = node->cases(); |
| 450 int length = cases->length(); | 445 int length = cases->length(); |
| 451 | 446 |
| 452 if (length < FastCaseSwitchMinCaseCount()) { | 447 if (length < FastCaseSwitchMinCaseCount()) { |
| 453 return false; | 448 return false; |
| 454 } | 449 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 void ArgumentsAccessStub::Generate(MacroAssembler* masm) { | 533 void ArgumentsAccessStub::Generate(MacroAssembler* masm) { |
| 539 switch (type_) { | 534 switch (type_) { |
| 540 case READ_LENGTH: GenerateReadLength(masm); break; | 535 case READ_LENGTH: GenerateReadLength(masm); break; |
| 541 case READ_ELEMENT: GenerateReadElement(masm); break; | 536 case READ_ELEMENT: GenerateReadElement(masm); break; |
| 542 case NEW_OBJECT: GenerateNewObject(masm); break; | 537 case NEW_OBJECT: GenerateNewObject(masm); break; |
| 543 } | 538 } |
| 544 } | 539 } |
| 545 | 540 |
| 546 | 541 |
| 547 } } // namespace v8::internal | 542 } } // namespace v8::internal |
| OLD | NEW |