Share ic data between unoptimized and optimized static calls.
This prevents duplicated javascript compatibility warnings.
R=srdjan@google.com
Review URL: https://codereview.chromium.org//322633002
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@37103 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 158631d..4c240e8 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -888,21 +888,32 @@
const Function& function,
intptr_t argument_count,
const Array& argument_names,
- LocationSummary* locs) {
- const Array& arguments_descriptor =
- Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
- argument_names));
+ LocationSummary* locs,
+ const ICData& ic_data) {
+ const Array& arguments_descriptor = Array::ZoneHandle(
+ ic_data.IsNull() ? ArgumentsDescriptor::New(argument_count,
+ argument_names)
+ : ic_data.arguments_descriptor());
// Proper reporting of Javascript incompatibilities requires icdata and
// may therefore prevent the optimization of some static calls.
if (is_optimizing() &&
!(FLAG_warn_on_javascript_compatibility &&
(MethodRecognizer::RecognizeKind(function) ==
MethodRecognizer::kObjectIdentical))) {
- EmitOptimizedStaticCall(function, arguments_descriptor, argument_count,
- deopt_id, token_pos, locs);
+ EmitOptimizedStaticCall(function, arguments_descriptor,
+ argument_count, deopt_id, token_pos, locs);
} else {
- EmitUnoptimizedStaticCall(function, arguments_descriptor, argument_count,
- deopt_id, token_pos, locs);
+ ICData& call_ic_data = ICData::ZoneHandle(ic_data.raw());
+ if (call_ic_data.IsNull()) {
+ call_ic_data = ICData::New(parsed_function().function(), // Caller fun.
+ String::Handle(function.name()),
+ arguments_descriptor,
+ deopt_id,
+ 0); // No arguments checked.
+ call_ic_data.AddTarget(function);
+ }
+ EmitUnoptimizedStaticCall(argument_count, deopt_id, token_pos, locs,
+ call_ic_data);
}
}
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 6546ff8..1d9a443 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -331,7 +331,8 @@
const Function& function,
intptr_t argument_count,
const Array& argument_names,
- LocationSummary* locs);
+ LocationSummary* locs,
+ const ICData& ic_data);
void GenerateNumberTypeCheck(Register kClassIdReg,
const AbstractType& type,
@@ -475,12 +476,11 @@
intptr_t token_pos,
LocationSummary* locs);
- void EmitUnoptimizedStaticCall(const Function& function,
- const Array& arguments_descriptor,
- intptr_t argument_count,
+ void EmitUnoptimizedStaticCall(intptr_t argument_count,
intptr_t deopt_id,
intptr_t token_pos,
- LocationSummary* locs);
+ LocationSummary* locs,
+ const ICData& ic_data);
// Type checking helper methods.
void CheckClassIds(Register class_id_reg,
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 55d6f8e..d22fc67 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -1281,27 +1281,11 @@
void FlowGraphCompiler::EmitUnoptimizedStaticCall(
- const Function& target_function,
- const Array& arguments_descriptor,
intptr_t argument_count,
intptr_t deopt_id,
intptr_t token_pos,
- LocationSummary* locs) {
- // TODO(srdjan): Improve performance of function recognition.
- MethodRecognizer::Kind recognized_kind =
- MethodRecognizer::RecognizeKind(target_function);
- int num_args_checked = 0;
- if ((recognized_kind == MethodRecognizer::kMathMin) ||
- (recognized_kind == MethodRecognizer::kMathMax)) {
- num_args_checked = 2;
- }
- const ICData& ic_data = ICData::ZoneHandle(
- ICData::New(parsed_function().function(), // Caller function.
- String::Handle(target_function.name()),
- arguments_descriptor,
- deopt_id,
- num_args_checked)); // No arguments checked.
- ic_data.AddTarget(target_function);
+ LocationSummary* locs,
+ const ICData& ic_data) {
uword label_address = 0;
if (ic_data.NumArgsTested() == 0) {
label_address = StubCode::ZeroArgsUnoptimizedStaticCallEntryPoint();
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index 9e4cb4e..66a29de 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -1287,27 +1287,11 @@
void FlowGraphCompiler::EmitUnoptimizedStaticCall(
- const Function& target_function,
- const Array& arguments_descriptor,
intptr_t argument_count,
intptr_t deopt_id,
intptr_t token_pos,
- LocationSummary* locs) {
- // TODO(srdjan): Improve performance of function recognition.
- MethodRecognizer::Kind recognized_kind =
- MethodRecognizer::RecognizeKind(target_function);
- int num_args_checked = 0;
- if ((recognized_kind == MethodRecognizer::kMathMin) ||
- (recognized_kind == MethodRecognizer::kMathMax)) {
- num_args_checked = 2;
- }
- const ICData& ic_data = ICData::ZoneHandle(
- ICData::New(parsed_function().function(), // Caller function.
- String::Handle(target_function.name()),
- arguments_descriptor,
- deopt_id,
- num_args_checked)); // No arguments checked.
- ic_data.AddTarget(target_function);
+ LocationSummary* locs,
+ const ICData& ic_data) {
uword label_address = 0;
if (ic_data.NumArgsTested() == 0) {
label_address = StubCode::ZeroArgsUnoptimizedStaticCallEntryPoint();
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 1f14dc6..1c4bfd3 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -1169,27 +1169,11 @@
void FlowGraphCompiler::EmitUnoptimizedStaticCall(
- const Function& target_function,
- const Array& arguments_descriptor,
intptr_t argument_count,
intptr_t deopt_id,
intptr_t token_pos,
- LocationSummary* locs) {
- // TODO(srdjan): Improve performance of function recognition.
- MethodRecognizer::Kind recognized_kind =
- MethodRecognizer::RecognizeKind(target_function);
- int num_args_checked = 0;
- if ((recognized_kind == MethodRecognizer::kMathMin) ||
- (recognized_kind == MethodRecognizer::kMathMax)) {
- num_args_checked = 2;
- }
- const ICData& ic_data = ICData::ZoneHandle(
- ICData::New(parsed_function().function(), // Caller function.
- String::Handle(target_function.name()),
- arguments_descriptor,
- deopt_id,
- num_args_checked)); // No arguments checked.
- ic_data.AddTarget(target_function);
+ LocationSummary* locs,
+ const ICData& ic_data) {
uword label_address = 0;
if (ic_data.NumArgsTested() == 0) {
label_address = StubCode::ZeroArgsUnoptimizedStaticCallEntryPoint();
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 8a75aef..0a69efa 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -1323,27 +1323,11 @@
void FlowGraphCompiler::EmitUnoptimizedStaticCall(
- const Function& target_function,
- const Array& arguments_descriptor,
intptr_t argument_count,
intptr_t deopt_id,
intptr_t token_pos,
- LocationSummary* locs) {
- // TODO(srdjan): Improve performance of function recognition.
- MethodRecognizer::Kind recognized_kind =
- MethodRecognizer::RecognizeKind(target_function);
- int num_args_checked = 0;
- if ((recognized_kind == MethodRecognizer::kMathMin) ||
- (recognized_kind == MethodRecognizer::kMathMax)) {
- num_args_checked = 2;
- }
- const ICData& ic_data = ICData::ZoneHandle(
- ICData::New(parsed_function().function(), // Caller function.
- String::Handle(target_function.name()),
- arguments_descriptor,
- deopt_id,
- num_args_checked)); // No arguments checked.
- ic_data.AddTarget(target_function);
+ LocationSummary* locs,
+ const ICData& ic_data) {
uword label_address = 0;
if (ic_data.NumArgsTested() == 0) {
label_address = StubCode::ZeroArgsUnoptimizedStaticCallEntryPoint();
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index d566e4e..0f5a1e5 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -1207,27 +1207,11 @@
void FlowGraphCompiler::EmitUnoptimizedStaticCall(
- const Function& target_function,
- const Array& arguments_descriptor,
intptr_t argument_count,
intptr_t deopt_id,
intptr_t token_pos,
- LocationSummary* locs) {
- // TODO(srdjan): Improve performance of function recognition.
- MethodRecognizer::Kind recognized_kind =
- MethodRecognizer::RecognizeKind(target_function);
- int num_args_checked = 0;
- if ((recognized_kind == MethodRecognizer::kMathMin) ||
- (recognized_kind == MethodRecognizer::kMathMax)) {
- num_args_checked = 2;
- }
- const ICData& ic_data = ICData::ZoneHandle(
- ICData::New(parsed_function().function(), // Caller function.
- String::Handle(target_function.name()),
- arguments_descriptor,
- deopt_id,
- num_args_checked)); // No arguments checked.
- ic_data.AddTarget(target_function);
+ LocationSummary* locs,
+ const ICData& ic_data) {
uword label_address = 0;
if (ic_data.NumArgsTested() == 0) {
label_address = StubCode::ZeroArgsUnoptimizedStaticCallEntryPoint();
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index a87ac3a..5283cea 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -2336,6 +2336,26 @@
void StaticCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+ ICData& call_ic_data = ICData::ZoneHandle(ic_data()->raw());
+ if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) {
+ const Array& arguments_descriptor =
+ Array::Handle(ArgumentsDescriptor::New(ArgumentCount(),
+ argument_names()));
+ // TODO(srdjan): Improve performance of function recognition.
+ MethodRecognizer::Kind recognized_kind =
+ MethodRecognizer::RecognizeKind(function());
+ int num_args_checked = 0;
+ if ((recognized_kind == MethodRecognizer::kMathMin) ||
+ (recognized_kind == MethodRecognizer::kMathMax)) {
+ num_args_checked = 2;
+ }
+ call_ic_data = ICData::New(compiler->parsed_function().function(),
+ String::Handle(function().name()),
+ arguments_descriptor,
+ deopt_id(),
+ num_args_checked); // No arguments checked.
+ call_ic_data.AddTarget(function());
+ }
if (!compiler->is_optimizing()) {
// Some static calls can be optimized by the optimizing compiler (e.g. sqrt)
// and therefore need a deoptimization descriptor.
@@ -2348,7 +2368,8 @@
function(),
ArgumentCount(),
argument_names(),
- locs());
+ locs(),
+ call_ic_data);
}
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index ebc5e5c..b8c98bd 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -1021,7 +1021,8 @@
CallFunction(),
kNumberOfArguments,
kNoArgumentNames,
- locs());
+ locs(),
+ ICData::Handle());
ASSERT(locs()->out(0).reg() == R0);
}
@@ -5141,7 +5142,8 @@
target,
kNumberOfArguments,
Object::null_array(), // No argument names.,
- locs());
+ locs(),
+ ICData::Handle());
__ Bind(&done);
}
@@ -5573,7 +5575,8 @@
target,
instance_call()->ArgumentCount(),
instance_call()->argument_names(),
- locs());
+ locs(),
+ ICData::Handle());
return;
}
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index ec073f7..da4e8b8 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -869,7 +869,8 @@
CallFunction(),
kNumberOfArguments,
kNoArgumentNames,
- locs());
+ locs(),
+ ICData::Handle());
ASSERT(locs()->out(0).reg() == R0);
}
@@ -4500,7 +4501,8 @@
target,
kNumberOfArguments,
Object::null_array(), // No argument names.,
- locs());
+ locs(),
+ ICData::Handle());
__ Bind(&done);
}
@@ -4882,7 +4884,8 @@
target,
instance_call()->ArgumentCount(),
instance_call()->argument_names(),
- locs());
+ locs(),
+ ICData::Handle());
return;
}
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 83e6f5d..fbf3eba 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -907,7 +907,8 @@
CallFunction(),
kNumberOfArguments,
kNoArgumentNames,
- locs());
+ locs(),
+ ICData::Handle());
ASSERT(locs()->out(0).reg() == EAX);
}
@@ -4945,8 +4946,9 @@
instance_call()->token_pos(),
target,
kNumberOfArguments,
- Object::null_array(), // No argument names.,
- locs());
+ Object::null_array(), // No argument names.
+ locs(),
+ ICData::Handle());
__ Bind(&done);
}
@@ -5422,7 +5424,8 @@
target,
instance_call()->ArgumentCount(),
instance_call()->argument_names(),
- locs());
+ locs(),
+ ICData::Handle());
return;
}
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index bec3d41..92b090d 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -987,7 +987,8 @@
CallFunction(),
kNumberOfArguments,
kNoArgumentNames,
- locs());
+ locs(),
+ ICData::Handle());
ASSERT(locs()->out(0).reg() == V0);
}
@@ -3860,7 +3861,8 @@
target,
kNumberOfArguments,
Object::null_array(), // No argument names.,
- locs());
+ locs(),
+ ICData::Handle());
__ Bind(&done);
}
@@ -4236,7 +4238,8 @@
target,
instance_call()->ArgumentCount(),
instance_call()->argument_names(),
- locs());
+ locs(),
+ ICData::Handle());
return;
}
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 6ce429c..0a82178 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -836,7 +836,8 @@
CallFunction(),
kNumberOfArguments,
kNoArgumentNames,
- locs());
+ locs(),
+ ICData::Handle());
ASSERT(locs()->out(0).reg() == RAX);
}
@@ -4791,7 +4792,8 @@
target,
kNumberOfArguments,
Object::null_array(), // No argument names.
- locs());
+ locs(),
+ ICData::Handle());
__ Bind(&done);
}
@@ -5324,7 +5326,8 @@
target,
instance_call()->ArgumentCount(),
instance_call()->argument_names(),
- locs());
+ locs(),
+ ICData::Handle());
return;
}
diff --git a/tests/standalone/javascript_compatibility_errors_test.dart b/tests/standalone/javascript_compatibility_errors_test.dart
index a9420b3..a384274 100644
--- a/tests/standalone/javascript_compatibility_errors_test.dart
+++ b/tests/standalone/javascript_compatibility_errors_test.dart
@@ -158,16 +158,18 @@
e is Error && "$e".contains("Javascript Compatibility Error");
main() {
- // Since the warning (or error in case of --warning_as_error) is issued at
- // most once per location, the Expect.throw must guard the whole loop.
- Expect.throws(
- () {
- for (var i = 0; i < 20; i++) {
- h(i, i * 1.0);
- }
- },
- isJavascriptCompatibilityError);
-
+ // The warning (or error in case of --warning_as_error) is issued at
+ // most once per location.
+ var numWarnings = 0;
+ for (var i = 0; i < 20; i++) {
+ try {
+ h(i, i * 1.0);
+ } catch(e) {
+ Expect.isTrue(isJavascriptCompatibilityError(e));
+ numWarnings++;
+ }
+ }
+ Expect.equals(1, numWarnings);
// No warnings (errors) should be issued after this point.
for (var i = 0; i < 20; i++) {
k(i * 1.0, i);