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

Side by Side Diff: runtime/vm/code_generator_x64.cc

Issue 9460015: Do not count invocations but usage of a function, i.e., increment a function's counter at IC calls … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 10 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/code_generator.h" 8 #include "vm/code_generator.h"
9 9
10 #include "lib/error.h" 10 #include "lib/error.h"
11 #include "vm/ast_printer.h" 11 #include "vm/ast_printer.h"
12 #include "vm/class_finalizer.h" 12 #include "vm/class_finalizer.h"
13 #include "vm/dart_entry.h" 13 #include "vm/dart_entry.h"
14 #include "vm/debugger.h" 14 #include "vm/debugger.h"
15 #include "vm/longjump.h" 15 #include "vm/longjump.h"
16 #include "vm/object.h" 16 #include "vm/object.h"
17 #include "vm/object_store.h" 17 #include "vm/object_store.h"
18 #include "vm/parser.h" 18 #include "vm/parser.h"
19 #include "vm/resolver.h" 19 #include "vm/resolver.h"
20 #include "vm/stub_code.h" 20 #include "vm/stub_code.h"
21 21
22 namespace dart { 22 namespace dart {
23 23
24 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree."); 24 DEFINE_FLAG(bool, print_ast, false, "Print abstract syntax tree.");
25 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); 25 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables.");
26 DEFINE_FLAG(bool, trace_functions, false, "Trace entry of each function."); 26 DEFINE_FLAG(bool, trace_functions, false, "Trace entry of each function.");
27 DEFINE_FLAG(int, optimization_invocation_threshold, 1000,
28 "number of invocations before a function is optimized, -1 means never.");
29 DECLARE_FLAG(bool, enable_type_checks); 27 DECLARE_FLAG(bool, enable_type_checks);
30 DECLARE_FLAG(bool, report_invocation_count);
31 DECLARE_FLAG(bool, trace_compiler); 28 DECLARE_FLAG(bool, trace_compiler);
32 29
33 #define __ assembler_-> 30 #define __ assembler_->
34 31
35 32
36 // TODO(regis): CodeGeneratorState, CodeGenerator::DescriptorList, and 33 // TODO(regis): CodeGeneratorState, CodeGenerator::DescriptorList, and
37 // CodeGenerator::HandlerList can probably be moved to code_generator.cc, since 34 // CodeGenerator::HandlerList can probably be moved to code_generator.cc, since
38 // they seem to be architecture independent. 35 // they seem to be architecture independent.
39 36
40 37
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 0, 258 0,
262 -1); 259 -1);
263 __ jmp(&StubCode::FixCallersTargetLabel()); 260 __ jmp(&StubCode::FixCallersTargetLabel());
264 } 261 }
265 262
266 263
267 void CodeGenerator::GenerateDeferredCode() { 264 void CodeGenerator::GenerateDeferredCode() {
268 } 265 }
269 266
270 267
271 // Pre entry code is called before the frame has been constructed: 268 // Pre entry code is called before the frame has been constructed.
272 // - check for stack overflow.
273 // - optionally count function invocations.
274 // - optionally trigger optimizing compiler if invocation threshold has been
275 // reached.
276 // Note that first 13 bytes may be patched with a jump. 269 // Note that first 13 bytes may be patched with a jump.
277 // TODO(srdjan): Add check that no object is inlined in the first 270 // TODO(srdjan): Add check that no object is inlined in the first
278 // 13 bytes (length of a jump instruction). 271 // 13 bytes (length of a jump instruction).
279 void CodeGenerator::GeneratePreEntryCode() { 272 void CodeGenerator::GeneratePreEntryCode() {
280 // Do not optimize if: 273 // Do not optimize if:
281 // - we count invocations. 274 // - we count invocations.
282 // - optimization disabled via negative 'optimization_invocation_threshold; 275 // - optimization disabled.
283 // - function is marked as non-optimizable. 276 // - function is marked as non-optimizable.
284 // - type checks are enabled. 277 // - type checks are enabled.
regis 2012/02/24 23:56:25 In the 32-bit version you added a TODO here: // TO
srdjan 2012/02/25 00:22:10 Done.
285 const bool may_optimize = 278 __ nop(8);
286 false && // TODO(srdjan): Remove once the optimizer is enabled on x64. 279 __ nop(5);
287 !FLAG_report_invocation_count &&
288 (FLAG_optimization_invocation_threshold >= 0) &&
289 !Isolate::Current()->debugger()->IsActive() &&
290 parsed_function_.function().is_optimizable();
291 // Count invocation and check.
292 if (FLAG_report_invocation_count || may_optimize) {
293 // TODO(turnidge): It would be nice to remove this nop. Right now
294 // we need it to make sure the function is still patchable.
295 __ nop(8);
296 __ nop(5);
297 const Function& function =
298 Function::ZoneHandle(parsed_function_.function().raw());
299 __ LoadObject(RAX, function);
300 __ movq(R8, FieldAddress(RAX, Function::invocation_counter_offset()));
301 __ incq(R8);
302 if (may_optimize) {
303 __ cmpq(R8, Immediate(FLAG_optimization_invocation_threshold));
304 __ j(GREATER, &StubCode::OptimizeInvokedFunctionLabel());
305 }
306 // R8 contains an integer value, not an object.
307 __ movq(FieldAddress(RAX, Function::invocation_counter_offset()), R8);
308 }
309 } 280 }
310 281
311 282
312 // Verify assumptions (in debug mode only). 283 // Verify assumptions (in debug mode only).
313 // - No two deopt descriptors have the same node id (deoptimization). 284 // - No two deopt descriptors have the same node id (deoptimization).
314 // - No two ic-call descriptors have the same node id (type feedback). 285 // - No two ic-call descriptors have the same node id (type feedback).
315 // - No two descriptors of same kind have the same PC. 286 // - No two descriptors of same kind have the same PC.
316 // A function without unique ids is marked as non-optimizable (e.g., because of 287 // A function without unique ids is marked as non-optimizable (e.g., because of
317 // finally blocks). 288 // finally blocks).
318 static void VerifyPcDescriptors(const PcDescriptors& descriptors, 289 static void VerifyPcDescriptors(const PcDescriptors& descriptors,
(...skipping 1586 matching lines...) Expand 10 before | Expand all | Expand 10 after
1905 1876
1906 // Call operator. 1877 // Call operator.
1907 GenerateBinaryOperatorCall(node->id(), node->token_index(), node->Name()); 1878 GenerateBinaryOperatorCall(node->id(), node->token_index(), node->Name());
1908 // Result is in RAX. 1879 // Result is in RAX.
1909 if (IsResultNeeded(node)) { 1880 if (IsResultNeeded(node)) {
1910 __ pushq(RAX); 1881 __ pushq(RAX);
1911 } 1882 }
1912 } 1883 }
1913 1884
1914 1885
1915 void CodeGenerator::CountBackwardLoop() {
1916 Label done;
1917 const Function& function =
1918 Function::ZoneHandle(parsed_function_.function().raw());
1919 __ LoadObject(RAX, function);
1920 __ movq(RBX, FieldAddress(RAX, Function::invocation_counter_offset()));
1921 __ incq(RBX);
1922 if (!FLAG_report_invocation_count) {
1923 // Prevent overflow.
1924 __ cmpq(RBX, Immediate(FLAG_optimization_invocation_threshold));
1925 __ j(GREATER, &done);
1926 }
1927 // RBX contains an integer value, not an object.
1928 __ movq(FieldAddress(RAX, Function::invocation_counter_offset()), RBX);
1929 __ Bind(&done);
1930 }
1931
1932
1933 void CodeGenerator::VisitWhileNode(WhileNode* node) { 1886 void CodeGenerator::VisitWhileNode(WhileNode* node) {
1934 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 1887 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1935 SourceLabel* label = node->label(); 1888 SourceLabel* label = node->label();
1936 __ Bind(label->continue_label()); 1889 __ Bind(label->continue_label());
1937 node->condition()->Visit(this); 1890 node->condition()->Visit(this);
1938 GenerateConditionTypeCheck(node->id(), node->condition()->token_index()); 1891 GenerateConditionTypeCheck(node->id(), node->condition()->token_index());
1939 __ popq(RAX); 1892 __ popq(RAX);
1940 __ LoadObject(RDX, bool_true); 1893 __ LoadObject(RDX, bool_true);
1941 __ cmpq(RAX, RDX); 1894 __ cmpq(RAX, RDX);
1942 __ j(NOT_EQUAL, label->break_label()); 1895 __ j(NOT_EQUAL, label->break_label());
1943 node->body()->Visit(this); 1896 node->body()->Visit(this);
1944 CountBackwardLoop();
1945 __ jmp(label->continue_label()); 1897 __ jmp(label->continue_label());
1946 __ Bind(label->break_label()); 1898 __ Bind(label->break_label());
1947 } 1899 }
1948 1900
1949 1901
1950 void CodeGenerator::VisitDoWhileNode(DoWhileNode* node) { 1902 void CodeGenerator::VisitDoWhileNode(DoWhileNode* node) {
1951 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 1903 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1952 SourceLabel* label = node->label(); 1904 SourceLabel* label = node->label();
1953 Label loop; 1905 Label loop;
1954 __ Bind(&loop); 1906 __ Bind(&loop);
1955 node->body()->Visit(this); 1907 node->body()->Visit(this);
1956 CountBackwardLoop();
1957 __ Bind(label->continue_label()); 1908 __ Bind(label->continue_label());
1958 node->condition()->Visit(this); 1909 node->condition()->Visit(this);
1959 GenerateConditionTypeCheck(node->id(), node->condition()->token_index()); 1910 GenerateConditionTypeCheck(node->id(), node->condition()->token_index());
1960 __ popq(RAX); 1911 __ popq(RAX);
1961 __ LoadObject(RDX, bool_true); 1912 __ LoadObject(RDX, bool_true);
1962 __ cmpq(RAX, RDX); 1913 __ cmpq(RAX, RDX);
1963 __ j(EQUAL, &loop); 1914 __ j(EQUAL, &loop);
1964 __ Bind(label->break_label()); 1915 __ Bind(label->break_label());
1965 } 1916 }
1966 1917
1967 1918
1968 void CodeGenerator::VisitForNode(ForNode* node) { 1919 void CodeGenerator::VisitForNode(ForNode* node) {
1969 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); 1920 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1970 node->initializer()->Visit(this); 1921 node->initializer()->Visit(this);
1971 SourceLabel* label = node->label(); 1922 SourceLabel* label = node->label();
1972 Label loop; 1923 Label loop;
1973 __ Bind(&loop); 1924 __ Bind(&loop);
1974 if (node->condition() != NULL) { 1925 if (node->condition() != NULL) {
1975 node->condition()->Visit(this); 1926 node->condition()->Visit(this);
1976 GenerateConditionTypeCheck(node->id(), node->condition()->token_index()); 1927 GenerateConditionTypeCheck(node->id(), node->condition()->token_index());
1977 __ popq(RAX); 1928 __ popq(RAX);
1978 __ LoadObject(RDX, bool_true); 1929 __ LoadObject(RDX, bool_true);
1979 __ cmpq(RAX, RDX); 1930 __ cmpq(RAX, RDX);
1980 __ j(NOT_EQUAL, label->break_label()); 1931 __ j(NOT_EQUAL, label->break_label());
1981 } 1932 }
1982 node->body()->Visit(this); 1933 node->body()->Visit(this);
1983 CountBackwardLoop();
1984 __ Bind(label->continue_label()); 1934 __ Bind(label->continue_label());
1985 node->increment()->Visit(this); 1935 node->increment()->Visit(this);
1986 __ jmp(&loop); 1936 __ jmp(&loop);
1987 __ Bind(label->break_label()); 1937 __ Bind(label->break_label());
1988 } 1938 }
1989 1939
1990 1940
1991 void CodeGenerator::VisitJumpNode(JumpNode* node) { 1941 void CodeGenerator::VisitJumpNode(JumpNode* node) {
1992 SourceLabel* label = node->label(); 1942 SourceLabel* label = node->label();
1993 1943
(...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after
2813 const Error& error = Error::Handle( 2763 const Error& error = Error::Handle(
2814 Parser::FormatError(script, token_index, "Error", format, args)); 2764 Parser::FormatError(script, token_index, "Error", format, args));
2815 va_end(args); 2765 va_end(args);
2816 Isolate::Current()->long_jump_base()->Jump(1, error); 2766 Isolate::Current()->long_jump_base()->Jump(1, error);
2817 UNREACHABLE(); 2767 UNREACHABLE();
2818 } 2768 }
2819 2769
2820 } // namespace dart 2770 } // namespace dart
2821 2771
2822 #endif // defined TARGET_ARCH_X64 2772 #endif // defined TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698