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

Unified Diff: src/codegen.cc

Issue 5002: Port of fast-case switch to ARM (Closed)
Patch Set: Updates based on review comments Created 12 years, 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/codegen.h ('k') | src/codegen-arm.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/codegen.cc
diff --git a/src/codegen.cc b/src/codegen.cc
index 7d50a69f20e969363fd6bac072d636242508304d..182971d5c99321ae5d356e467ee8d9e28e83dd96 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -251,6 +251,107 @@ bool CodeGenerator::CheckForInlineRuntimeCall(CallRuntime* node) {
}
+void CodeGenerator::GenerateFastCaseSwitchStatement(
+ SwitchStatement *node, int min_index, int range, int default_index) {
+
+ ZoneList<CaseClause*>* cases = node->cases();
+ int length = cases->length();
+
+ // Label pointer per number in range
+ SmartPointer<Label*> case_targets(NewArray<Label*>(range));
+
+ // Label per switch case
+ SmartPointer<Label> case_labels(NewArray<Label>(length));
+
+ Label* fail_label = (default_index >= 0 ? &(case_labels[default_index])
+ : node->break_target());
+
+ // Populate array of label pointers for each number in the range.
+ // Initally put the failure label everywhere.
+ for (int i = 0; i < range; i++) {
+ case_targets[i] = fail_label;
+ }
+
+ // Overwrite with label of a case for the number value of that case.
+ // (In reverse order, so that if the same label occurs twice, the
+ // first one wins).
+ for (int i = length-1; i >= 0 ; i--) {
+ CaseClause* clause = cases->at(i);
+ if (!clause->is_default()) {
+ Object* label_value = *(clause->label()->AsLiteral()->handle());
+ int case_value = Smi::cast(label_value)->value();
+ case_targets[case_value - min_index] = &(case_labels[i]);
+ }
+ }
+
+ GenerateFastCaseSwitchJumpTable(node, min_index, range, fail_label,
+ case_targets, case_labels);
+}
+
+void CodeGenerator::GenerateFastCaseSwitchCases(
+ SwitchStatement* node, SmartPointer<Label> &case_labels) {
+
+ ZoneList<CaseClause*>* cases = node->cases();
+ int length = cases->length();
+
+ for (int i = 0; i < length; i++) {
+ Comment cmnt(masm(), "[ case clause");
+ masm()->bind(&(case_labels[i]));
+ VisitStatements(cases->at(i)->statements());
+ }
+
+ masm()->bind(node->break_target());
+}
+
+
+bool CodeGenerator::TryGenerateFastCaseSwitchStatement(SwitchStatement* node) {
+ ZoneList<CaseClause*>* cases = node->cases();
+ int length = cases->length();
+
+ if (length < FastCaseSwitchMinCaseCount()) {
+ return false;
+ }
+
+ // Test whether fast-case should be used.
+ int default_index = -1;
+ int min_index = Smi::kMaxValue;
+ int max_index = Smi::kMinValue;
+ for (int i = 0; i < length; i++) {
+ CaseClause* clause = cases->at(i);
+ if (clause->is_default()) {
+ if (default_index >= 0) {
+ return false; // More than one default label:
+ // Defer to normal case for error.
+ }
+ default_index = i;
+ } else {
+ Expression* label = clause->label();
+ Literal* literal = label->AsLiteral();
+ if (literal == NULL) {
+ return false; // fail fast case
+ }
+ Object* value = *(literal->handle());
+ if (!value->IsSmi()) {
+ return false;
+ }
+ int smi = Smi::cast(value)->value();
+ if (smi < min_index) { min_index = smi; }
+ if (smi > max_index) { max_index = smi; }
+ }
+ }
+
+ // All labels are known to be Smis.
+ int range = max_index - min_index + 1; // |min..max| inclusive
+ if (range / FastCaseSwitchMaxOverheadFactor() > length) {
+ return false; // range of labels is too sparse
+ }
+
+ // Optimization accepted, generate code.
+ GenerateFastCaseSwitchStatement(node, min_index, range, default_index);
+ return true;
+}
+
+
const char* RuntimeStub::GetName() {
return Runtime::FunctionForId(id_)->stub_name;
}
« no previous file with comments | « src/codegen.h ('k') | src/codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698