| Index: src/hydrogen.cc
|
| ===================================================================
|
| --- src/hydrogen.cc (revision 12582)
|
| +++ src/hydrogen.cc (working copy)
|
| @@ -1152,6 +1152,71 @@
|
| }
|
|
|
|
|
| +void HGraph::OptimizeStringCalls() {
|
| + HPhase phase("Optimize string calls", this);
|
| +
|
| + Handle<JSBuiltinsObject> builtins(
|
| + start_environment_->closure()->context()->builtins());
|
| + const int kNumFunctions = 4;
|
| + const char* function_syms[kNumFunctions] = {
|
| + "RegExpExec",
|
| + "StringMatch",
|
| + "StringReplace",
|
| + "StringSplit",
|
| + };
|
| + const char* function_noresult_syms[kNumFunctions] = {
|
| + "RegExpExecNoResult",
|
| + "StringMatchNoResult",
|
| + "StringReplaceNoResult",
|
| + "StringSplitNoResult",
|
| + };
|
| + Handle<JSFunction> functions[kNumFunctions];
|
| + Handle<JSFunction> noresult_functions[kNumFunctions];
|
| +
|
| + for (int i = 0; i < kNumFunctions; ++i) {
|
| + Handle<String> sym = FACTORY->LookupAsciiSymbol(function_syms[i]);
|
| + { MaybeObject* maybe_function = builtins->GetProperty(*sym);
|
| + Object* obj;
|
| + if (!maybe_function->ToObject(&obj)) return;
|
| + if (!obj->IsJSFunction()) return;
|
| + functions[i] = Handle<JSFunction>(JSFunction::cast(obj));
|
| + }
|
| +
|
| + Handle<String> noresult_sym =
|
| + FACTORY->LookupAsciiSymbol(function_noresult_syms[i]);
|
| + { MaybeObject* maybe_function = builtins->GetProperty(*noresult_sym);
|
| + Object* obj;
|
| + if (!maybe_function->ToObject(&obj)) return;
|
| + if (!obj->IsJSFunction()) return;
|
| + noresult_functions[i] = Handle<JSFunction>(JSFunction::cast(obj));
|
| + }
|
| + }
|
| +
|
| + for (int i = 0; i < blocks_.length(); i++) {
|
| + for (HInstruction* instr = blocks_[i]->first();
|
| + instr != NULL;
|
| + instr = instr->next()) {
|
| + if (instr->IsCallConstantFunction() && instr->HasNoUses()) {
|
| + HCallConstantFunction* call = HCallConstantFunction::cast(instr);
|
| + Handle<JSFunction> function = call->function();
|
| + Handle<JSFunction> replace_function;
|
| + for (int i = 0; i < kNumFunctions; ++i) {
|
| + if (*function == *functions[i])
|
| + replace_function = noresult_functions[i];
|
| + }
|
| + if (!replace_function.is_null()) {
|
| + HCallConstantFunction* call_noresult =
|
| + new(zone()) HCallConstantFunction(replace_function,
|
| + call->argument_count());
|
| + call_noresult->InsertBefore(call);
|
| + call->Unlink();
|
| + }
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| bool HGraph::CheckArgumentsPhiUses() {
|
| int block_count = blocks_.length();
|
| for (int i = 0; i < block_count; ++i) {
|
| @@ -7601,7 +7666,8 @@
|
| }
|
|
|
| if (CallStubCompiler::HasCustomCallGenerator(expr->target()) ||
|
| - expr->check_type() != RECEIVER_MAP_CHECK) {
|
| + (expr->check_type() != RECEIVER_MAP_CHECK &&
|
| + expr->check_type() != STRING_CHECK)) {
|
| // When the target has a custom call IC generator, use the IC,
|
| // because it is likely to generate better code. Also use the IC
|
| // when a primitive receiver check is required.
|
|
|