Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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" |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 295 __ nop(5); | 295 __ nop(5); |
| 296 const Function& function = | 296 const Function& function = |
| 297 Function::ZoneHandle(parsed_function_.function().raw()); | 297 Function::ZoneHandle(parsed_function_.function().raw()); |
| 298 __ LoadObject(RAX, function); | 298 __ LoadObject(RAX, function); |
| 299 __ movq(R8, FieldAddress(RAX, Function::invocation_counter_offset())); | 299 __ movq(R8, FieldAddress(RAX, Function::invocation_counter_offset())); |
| 300 __ incq(R8); | 300 __ incq(R8); |
| 301 if (may_optimize) { | 301 if (may_optimize) { |
| 302 __ cmpq(R8, Immediate(FLAG_optimization_invocation_threshold)); | 302 __ cmpq(R8, Immediate(FLAG_optimization_invocation_threshold)); |
| 303 __ j(GREATER, &StubCode::OptimizeInvokedFunctionLabel()); | 303 __ j(GREATER, &StubCode::OptimizeInvokedFunctionLabel()); |
| 304 } | 304 } |
| 305 // R8 contains an integer value, not an object. | |
|
cshapiro
2011/12/21 19:45:06
Presumably, "integer value" means raw- or unboxed-
srdjan
2011/12/21 21:29:12
That is correct. The increment operation could als
| |
| 305 __ movq(FieldAddress(RAX, Function::invocation_counter_offset()), R8); | 306 __ movq(FieldAddress(RAX, Function::invocation_counter_offset()), R8); |
| 306 } | 307 } |
| 307 } | 308 } |
| 308 | 309 |
| 309 | 310 |
| 310 // Verify assumptions (in debug mode only). | 311 // Verify assumptions (in debug mode only). |
| 311 // - No two deopt descriptors have the same node id (deoptimization). | 312 // - No two deopt descriptors have the same node id (deoptimization). |
| 312 // - No two ic-call descriptors have the same node id (type feedback). | 313 // - No two ic-call descriptors have the same node id (type feedback). |
| 313 // - No two descriptors of same kind have the same PC. | 314 // - No two descriptors of same kind have the same PC. |
| 314 // A function without unique ids is marked as non-optimizable (e.g., because of | 315 // A function without unique ids is marked as non-optimizable (e.g., because of |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 Register scratch) { | 400 Register scratch) { |
| 400 if (variable.is_captured()) { | 401 if (variable.is_captured()) { |
| 401 // The variable lives in the context. | 402 // The variable lives in the context. |
| 402 int delta = state()->context_level() - variable.owner()->context_level(); | 403 int delta = state()->context_level() - variable.owner()->context_level(); |
| 403 ASSERT(delta >= 0); | 404 ASSERT(delta >= 0); |
| 404 Register base = CTX; | 405 Register base = CTX; |
| 405 while (delta-- > 0) { | 406 while (delta-- > 0) { |
| 406 __ movq(scratch, FieldAddress(base, Context::parent_offset())); | 407 __ movq(scratch, FieldAddress(base, Context::parent_offset())); |
| 407 base = scratch; | 408 base = scratch; |
| 408 } | 409 } |
| 409 __ movq(FieldAddress(base, Context::variable_offset(variable.index())), | 410 __ StoreIntoObject( |
| 410 src); | 411 base, |
| 412 FieldAddress(base, Context::variable_offset(variable.index())), | |
| 413 src); | |
| 411 } else { | 414 } else { |
| 412 // The variable lives in the current stack frame. | 415 // The variable lives in the current stack frame. |
| 413 __ movq(Address(RBP, variable.index() * kWordSize), src); | 416 __ movq(Address(RBP, variable.index() * kWordSize), src); |
| 414 } | 417 } |
| 415 } | 418 } |
| 416 | 419 |
| 417 | 420 |
| 418 void CodeGenerator::GeneratePushVariable(const LocalVariable& variable, | 421 void CodeGenerator::GeneratePushVariable(const LocalVariable& variable, |
| 419 Register scratch) { | 422 Register scratch) { |
| 420 if (variable.is_captured()) { | 423 if (variable.is_captured()) { |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 927 (scope != NULL) ? scope->num_context_variables() : 0; | 930 (scope != NULL) ? scope->num_context_variables() : 0; |
| 928 if (num_context_variables > 0) { | 931 if (num_context_variables > 0) { |
| 929 // The loop local scope declares variables that are captured. | 932 // The loop local scope declares variables that are captured. |
| 930 // Allocate and chain a new context. | 933 // Allocate and chain a new context. |
| 931 __ movq(R10, Immediate(num_context_variables)); | 934 __ movq(R10, Immediate(num_context_variables)); |
| 932 const ExternalLabel label("alloc_context", | 935 const ExternalLabel label("alloc_context", |
| 933 StubCode::AllocateContextEntryPoint()); | 936 StubCode::AllocateContextEntryPoint()); |
| 934 GenerateCall(node_sequence->token_index(), &label); | 937 GenerateCall(node_sequence->token_index(), &label); |
| 935 | 938 |
| 936 // Chain the new context in RAX to its parent in CTX. | 939 // Chain the new context in RAX to its parent in CTX. |
| 937 __ movq(FieldAddress(RAX, Context::parent_offset()), CTX); | 940 __ StoreIntoObject(RAX, |
| 941 FieldAddress(RAX, Context::parent_offset()), | |
| 942 CTX); | |
| 938 // Set new context as current context. | 943 // Set new context as current context. |
| 939 __ movq(CTX, RAX); | 944 __ movq(CTX, RAX); |
| 940 state()->set_context_level(scope->context_level()); | 945 state()->set_context_level(scope->context_level()); |
| 941 | 946 |
| 942 // If this node_sequence is the body of the function being compiled, copy | 947 // If this node_sequence is the body of the function being compiled, copy |
| 943 // the captured parameters from the frame into the context. | 948 // the captured parameters from the frame into the context. |
| 944 if (node_sequence == parsed_function_.node_sequence()) { | 949 if (node_sequence == parsed_function_.node_sequence()) { |
| 945 ASSERT(scope->context_level() == 1); | 950 ASSERT(scope->context_level() == 1); |
| 946 const Immediate raw_null = | 951 const Immediate raw_null = |
| 947 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 952 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| (...skipping 950 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1898 const Function& function = | 1903 const Function& function = |
| 1899 Function::ZoneHandle(parsed_function_.function().raw()); | 1904 Function::ZoneHandle(parsed_function_.function().raw()); |
| 1900 __ LoadObject(RAX, function); | 1905 __ LoadObject(RAX, function); |
| 1901 __ movq(RBX, FieldAddress(RAX, Function::invocation_counter_offset())); | 1906 __ movq(RBX, FieldAddress(RAX, Function::invocation_counter_offset())); |
| 1902 __ incq(RBX); | 1907 __ incq(RBX); |
| 1903 if (!FLAG_report_invocation_count) { | 1908 if (!FLAG_report_invocation_count) { |
| 1904 // Prevent overflow. | 1909 // Prevent overflow. |
| 1905 __ cmpq(RBX, Immediate(FLAG_optimization_invocation_threshold)); | 1910 __ cmpq(RBX, Immediate(FLAG_optimization_invocation_threshold)); |
| 1906 __ j(GREATER, &done); | 1911 __ j(GREATER, &done); |
| 1907 } | 1912 } |
| 1913 // RBX contains an integer value, not an object. | |
| 1908 __ movq(FieldAddress(RAX, Function::invocation_counter_offset()), RBX); | 1914 __ movq(FieldAddress(RAX, Function::invocation_counter_offset()), RBX); |
| 1909 __ Bind(&done); | 1915 __ Bind(&done); |
| 1910 } | 1916 } |
| 1911 | 1917 |
| 1912 | 1918 |
| 1913 void CodeGenerator::VisitWhileNode(WhileNode* node) { | 1919 void CodeGenerator::VisitWhileNode(WhileNode* node) { |
| 1914 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | 1920 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); |
| 1915 SourceLabel* label = node->label(); | 1921 SourceLabel* label = node->label(); |
| 1916 __ Bind(label->continue_label()); | 1922 __ Bind(label->continue_label()); |
| 1917 node->condition()->Visit(this); | 1923 node->condition()->Visit(this); |
| (...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2795 message_buffer, kMessageBufferSize, | 2801 message_buffer, kMessageBufferSize, |
| 2796 format, args); | 2802 format, args); |
| 2797 va_end(args); | 2803 va_end(args); |
| 2798 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); | 2804 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); |
| 2799 UNREACHABLE(); | 2805 UNREACHABLE(); |
| 2800 } | 2806 } |
| 2801 | 2807 |
| 2802 } // namespace dart | 2808 } // namespace dart |
| 2803 | 2809 |
| 2804 #endif // defined TARGET_ARCH_X64 | 2810 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |