| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 int count, | 277 int count, |
| 278 BailoutType type) { | 278 BailoutType type) { |
| 279 TableEntryGenerator generator(masm, type, count); | 279 TableEntryGenerator generator(masm, type, count); |
| 280 generator.Generate(); | 280 generator.Generate(); |
| 281 } | 281 } |
| 282 | 282 |
| 283 | 283 |
| 284 void Deoptimizer::VisitAllOptimizedFunctionsForContext( | 284 void Deoptimizer::VisitAllOptimizedFunctionsForContext( |
| 285 Context* context, OptimizedFunctionVisitor* visitor) { | 285 Context* context, OptimizedFunctionVisitor* visitor) { |
| 286 Isolate* isolate = context->GetIsolate(); | 286 Isolate* isolate = context->GetIsolate(); |
| 287 ZoneScope zone_scope(isolate->runtime_zone(), DELETE_ON_EXIT); | 287 Zone zone(isolate); |
| 288 DisallowHeapAllocation no_allocation; | 288 DisallowHeapAllocation no_allocation; |
| 289 | 289 |
| 290 ASSERT(context->IsNativeContext()); | 290 ASSERT(context->IsNativeContext()); |
| 291 | 291 |
| 292 visitor->EnterContext(context); | 292 visitor->EnterContext(context); |
| 293 | 293 |
| 294 // Create a snapshot of the optimized functions list. This is needed because | 294 // Create a snapshot of the optimized functions list. This is needed because |
| 295 // visitors might remove more than one link from the list at once. | 295 // visitors might remove more than one link from the list at once. |
| 296 ZoneList<JSFunction*> snapshot(1, isolate->runtime_zone()); | 296 ZoneList<JSFunction*> snapshot(1, &zone); |
| 297 Object* element = context->OptimizedFunctionsListHead(); | 297 Object* element = context->OptimizedFunctionsListHead(); |
| 298 while (!element->IsUndefined()) { | 298 while (!element->IsUndefined()) { |
| 299 JSFunction* element_function = JSFunction::cast(element); | 299 JSFunction* element_function = JSFunction::cast(element); |
| 300 snapshot.Add(element_function, isolate->runtime_zone()); | 300 snapshot.Add(element_function, &zone); |
| 301 element = element_function->next_function_link(); | 301 element = element_function->next_function_link(); |
| 302 } | 302 } |
| 303 | 303 |
| 304 // Run through the snapshot of optimized functions and visit them. | 304 // Run through the snapshot of optimized functions and visit them. |
| 305 for (int i = 0; i < snapshot.length(); ++i) { | 305 for (int i = 0; i < snapshot.length(); ++i) { |
| 306 visitor->VisitFunction(snapshot.at(i)); | 306 visitor->VisitFunction(snapshot.at(i)); |
| 307 } | 307 } |
| 308 | 308 |
| 309 visitor->LeaveContext(context); | 309 visitor->LeaveContext(context); |
| 310 } | 310 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 } | 413 } |
| 414 } | 414 } |
| 415 | 415 |
| 416 | 416 |
| 417 void Deoptimizer::DeoptimizeFunction(JSFunction* function) { | 417 void Deoptimizer::DeoptimizeFunction(JSFunction* function) { |
| 418 if (!function->IsOptimized()) return; | 418 if (!function->IsOptimized()) return; |
| 419 Code* code = function->code(); | 419 Code* code = function->code(); |
| 420 Context* context = function->context()->native_context(); | 420 Context* context = function->context()->native_context(); |
| 421 Isolate* isolate = context->GetIsolate(); | 421 Isolate* isolate = context->GetIsolate(); |
| 422 Object* undefined = isolate->heap()->undefined_value(); | 422 Object* undefined = isolate->heap()->undefined_value(); |
| 423 Zone* zone = isolate->runtime_zone(); | 423 Zone zone(isolate); |
| 424 ZoneScope zone_scope(zone, DELETE_ON_EXIT); | 424 ZoneList<Code*> codes(1, &zone); |
| 425 ZoneList<Code*> codes(1, zone); | |
| 426 DeoptimizeWithMatchingCodeFilter filter(code); | 425 DeoptimizeWithMatchingCodeFilter filter(code); |
| 427 PartitionOptimizedFunctions(context, &filter, &codes, zone, undefined); | 426 PartitionOptimizedFunctions(context, &filter, &codes, &zone, undefined); |
| 428 ASSERT_EQ(1, codes.length()); | 427 ASSERT_EQ(1, codes.length()); |
| 429 DeoptimizeFunctionWithPreparedFunctionList( | 428 DeoptimizeFunctionWithPreparedFunctionList( |
| 430 JSFunction::cast(codes.at(0)->deoptimizing_functions())); | 429 JSFunction::cast(codes.at(0)->deoptimizing_functions())); |
| 431 codes.at(0)->set_deoptimizing_functions(undefined); | 430 codes.at(0)->set_deoptimizing_functions(undefined); |
| 432 } | 431 } |
| 433 | 432 |
| 434 | 433 |
| 435 void Deoptimizer::DeoptimizeAllFunctionsForContext( | 434 void Deoptimizer::DeoptimizeAllFunctionsForContext( |
| 436 Context* context, OptimizedFunctionFilter* filter) { | 435 Context* context, OptimizedFunctionFilter* filter) { |
| 437 ASSERT(context->IsNativeContext()); | 436 ASSERT(context->IsNativeContext()); |
| 438 Isolate* isolate = context->GetIsolate(); | 437 Isolate* isolate = context->GetIsolate(); |
| 439 Object* undefined = isolate->heap()->undefined_value(); | 438 Object* undefined = isolate->heap()->undefined_value(); |
| 440 Zone* zone = isolate->runtime_zone(); | 439 Zone zone(isolate); |
| 441 ZoneScope zone_scope(zone, DELETE_ON_EXIT); | 440 ZoneList<Code*> codes(1, &zone); |
| 442 ZoneList<Code*> codes(1, zone); | 441 PartitionOptimizedFunctions(context, filter, &codes, &zone, undefined); |
| 443 PartitionOptimizedFunctions(context, filter, &codes, zone, undefined); | |
| 444 for (int i = 0; i < codes.length(); ++i) { | 442 for (int i = 0; i < codes.length(); ++i) { |
| 445 DeoptimizeFunctionWithPreparedFunctionList( | 443 DeoptimizeFunctionWithPreparedFunctionList( |
| 446 JSFunction::cast(codes.at(i)->deoptimizing_functions())); | 444 JSFunction::cast(codes.at(i)->deoptimizing_functions())); |
| 447 codes.at(i)->set_deoptimizing_functions(undefined); | 445 codes.at(i)->set_deoptimizing_functions(undefined); |
| 448 } | 446 } |
| 449 } | 447 } |
| 450 | 448 |
| 451 | 449 |
| 452 void Deoptimizer::DeoptimizeAllFunctionsWith(Isolate* isolate, | 450 void Deoptimizer::DeoptimizeAllFunctionsWith(Isolate* isolate, |
| 453 OptimizedFunctionFilter* filter) { | 451 OptimizedFunctionFilter* filter) { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 deferred_heap_numbers_(0), | 538 deferred_heap_numbers_(0), |
| 541 trace_(false) { | 539 trace_(false) { |
| 542 // For COMPILED_STUBs called from builtins, the function pointer is a SMI | 540 // For COMPILED_STUBs called from builtins, the function pointer is a SMI |
| 543 // indicating an internal frame. | 541 // indicating an internal frame. |
| 544 if (function->IsSmi()) { | 542 if (function->IsSmi()) { |
| 545 function = NULL; | 543 function = NULL; |
| 546 } | 544 } |
| 547 if (function != NULL && function->IsOptimized()) { | 545 if (function != NULL && function->IsOptimized()) { |
| 548 function->shared()->increment_deopt_count(); | 546 function->shared()->increment_deopt_count(); |
| 549 if (bailout_type_ == Deoptimizer::SOFT) { | 547 if (bailout_type_ == Deoptimizer::SOFT) { |
| 548 isolate->counters()->soft_deopts_executed()->Increment(); |
| 550 // Soft deopts shouldn't count against the overall re-optimization count | 549 // Soft deopts shouldn't count against the overall re-optimization count |
| 551 // that can eventually lead to disabling optimization for a function. | 550 // that can eventually lead to disabling optimization for a function. |
| 552 int opt_count = function->shared()->opt_count(); | 551 int opt_count = function->shared()->opt_count(); |
| 553 if (opt_count > 0) opt_count--; | 552 if (opt_count > 0) opt_count--; |
| 554 function->shared()->set_opt_count(opt_count); | 553 function->shared()->set_opt_count(opt_count); |
| 555 } | 554 } |
| 556 } | 555 } |
| 557 compiled_code_ = FindOptimizedCode(function, optimized_code); | 556 compiled_code_ = FindOptimizedCode(function, optimized_code); |
| 558 StackFrame::Type frame_type = function == NULL | 557 StackFrame::Type frame_type = function == NULL |
| 559 ? StackFrame::STUB | 558 ? StackFrame::STUB |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 781 case Translation::REGISTER: | 780 case Translation::REGISTER: |
| 782 case Translation::INT32_REGISTER: | 781 case Translation::INT32_REGISTER: |
| 783 case Translation::UINT32_REGISTER: | 782 case Translation::UINT32_REGISTER: |
| 784 case Translation::DOUBLE_REGISTER: | 783 case Translation::DOUBLE_REGISTER: |
| 785 case Translation::STACK_SLOT: | 784 case Translation::STACK_SLOT: |
| 786 case Translation::INT32_STACK_SLOT: | 785 case Translation::INT32_STACK_SLOT: |
| 787 case Translation::UINT32_STACK_SLOT: | 786 case Translation::UINT32_STACK_SLOT: |
| 788 case Translation::DOUBLE_STACK_SLOT: | 787 case Translation::DOUBLE_STACK_SLOT: |
| 789 case Translation::LITERAL: | 788 case Translation::LITERAL: |
| 790 case Translation::ARGUMENTS_OBJECT: | 789 case Translation::ARGUMENTS_OBJECT: |
| 791 case Translation::DUPLICATE: | |
| 792 default: | 790 default: |
| 793 UNREACHABLE(); | 791 UNREACHABLE(); |
| 794 break; | 792 break; |
| 795 } | 793 } |
| 796 } | 794 } |
| 797 | 795 |
| 798 // Print some helpful diagnostic information. | 796 // Print some helpful diagnostic information. |
| 799 if (trace_) { | 797 if (trace_) { |
| 800 double ms = static_cast<double>(OS::Ticks() - start) / 1000; | 798 double ms = static_cast<double>(OS::Ticks() - start) / 1000; |
| 801 int index = output_count_ - 1; // Index of the topmost frame. | 799 int index = output_count_ - 1; // Index of the topmost frame. |
| (...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 value = arg_count_known ? caller_arg_count : the_hole; | 1502 value = arg_count_known ? caller_arg_count : the_hole; |
| 1505 output_frame->SetFrameSlot(length_frame_offset, value); | 1503 output_frame->SetFrameSlot(length_frame_offset, value); |
| 1506 if (trace_) { | 1504 if (trace_) { |
| 1507 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1505 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1508 V8PRIxPTR " ; args.length %s\n", | 1506 V8PRIxPTR " ; args.length %s\n", |
| 1509 top_address + length_frame_offset, length_frame_offset, value, | 1507 top_address + length_frame_offset, length_frame_offset, value, |
| 1510 arg_count_known ? "" : "(the hole)"); | 1508 arg_count_known ? "" : "(the hole)"); |
| 1511 } | 1509 } |
| 1512 | 1510 |
| 1513 output_frame_offset -= kPointerSize; | 1511 output_frame_offset -= kPointerSize; |
| 1514 value = frame_ptr - (output_frame_size - output_frame_offset) - | 1512 value = frame_ptr + StandardFrameConstants::kCallerSPOffset - |
| 1515 StandardFrameConstants::kMarkerOffset + kPointerSize; | 1513 (output_frame_size - output_frame_offset) + kPointerSize; |
| 1516 output_frame->SetFrameSlot(output_frame_offset, value); | 1514 output_frame->SetFrameSlot(output_frame_offset, value); |
| 1517 if (trace_) { | 1515 if (trace_) { |
| 1518 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" | 1516 PrintF(" 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" |
| 1519 V8PRIxPTR " ; args*\n", | 1517 V8PRIxPTR " ; args*\n", |
| 1520 top_address + output_frame_offset, output_frame_offset, value); | 1518 top_address + output_frame_offset, output_frame_offset, value); |
| 1521 } | 1519 } |
| 1522 | 1520 |
| 1523 // Copy the register parameters to the failure frame. | 1521 // Copy the register parameters to the failure frame. |
| 1524 for (int i = 0; i < descriptor->register_param_count_; ++i) { | 1522 for (int i = 0; i < descriptor->register_param_count_; ++i) { |
| 1525 output_frame_offset -= kPointerSize; | 1523 output_frame_offset -= kPointerSize; |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1717 return "heap number"; | 1715 return "heap number"; |
| 1718 } | 1716 } |
| 1719 | 1717 |
| 1720 | 1718 |
| 1721 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, | 1719 void Deoptimizer::DoTranslateObject(TranslationIterator* iterator, |
| 1722 int object_opcode, | 1720 int object_opcode, |
| 1723 int field_index) { | 1721 int field_index) { |
| 1724 disasm::NameConverter converter; | 1722 disasm::NameConverter converter; |
| 1725 Address object_slot = deferred_objects_.last().slot_address(); | 1723 Address object_slot = deferred_objects_.last().slot_address(); |
| 1726 | 1724 |
| 1727 // Ignore commands marked as duplicate and act on the first non-duplicate. | |
| 1728 Translation::Opcode opcode = | 1725 Translation::Opcode opcode = |
| 1729 static_cast<Translation::Opcode>(iterator->Next()); | 1726 static_cast<Translation::Opcode>(iterator->Next()); |
| 1730 while (opcode == Translation::DUPLICATE) { | |
| 1731 opcode = static_cast<Translation::Opcode>(iterator->Next()); | |
| 1732 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); | |
| 1733 opcode = static_cast<Translation::Opcode>(iterator->Next()); | |
| 1734 } | |
| 1735 | 1727 |
| 1736 switch (opcode) { | 1728 switch (opcode) { |
| 1737 case Translation::BEGIN: | 1729 case Translation::BEGIN: |
| 1738 case Translation::JS_FRAME: | 1730 case Translation::JS_FRAME: |
| 1739 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 1731 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
| 1740 case Translation::CONSTRUCT_STUB_FRAME: | 1732 case Translation::CONSTRUCT_STUB_FRAME: |
| 1741 case Translation::GETTER_STUB_FRAME: | 1733 case Translation::GETTER_STUB_FRAME: |
| 1742 case Translation::SETTER_STUB_FRAME: | 1734 case Translation::SETTER_STUB_FRAME: |
| 1743 case Translation::COMPILED_STUB_FRAME: | 1735 case Translation::COMPILED_STUB_FRAME: |
| 1744 case Translation::ARGUMENTS_OBJECT: | 1736 case Translation::ARGUMENTS_OBJECT: |
| 1745 case Translation::DUPLICATE: | |
| 1746 UNREACHABLE(); | 1737 UNREACHABLE(); |
| 1747 return; | 1738 return; |
| 1748 | 1739 |
| 1749 case Translation::REGISTER: { | 1740 case Translation::REGISTER: { |
| 1750 int input_reg = iterator->Next(); | 1741 int input_reg = iterator->Next(); |
| 1751 intptr_t input_value = input_->GetRegister(input_reg); | 1742 intptr_t input_value = input_->GetRegister(input_reg); |
| 1752 if (trace_) { | 1743 if (trace_) { |
| 1753 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", | 1744 PrintF(" object @0x%08" V8PRIxPTR ": [field #%d] <- ", |
| 1754 reinterpret_cast<intptr_t>(object_slot), | 1745 reinterpret_cast<intptr_t>(object_slot), |
| 1755 field_index); | 1746 field_index); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1918 | 1909 |
| 1919 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, | 1910 void Deoptimizer::DoTranslateCommand(TranslationIterator* iterator, |
| 1920 int frame_index, | 1911 int frame_index, |
| 1921 unsigned output_offset, | 1912 unsigned output_offset, |
| 1922 DeoptimizerTranslatedValueType value_type) { | 1913 DeoptimizerTranslatedValueType value_type) { |
| 1923 disasm::NameConverter converter; | 1914 disasm::NameConverter converter; |
| 1924 // A GC-safe temporary placeholder that we can put in the output frame. | 1915 // A GC-safe temporary placeholder that we can put in the output frame. |
| 1925 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); | 1916 const intptr_t kPlaceholder = reinterpret_cast<intptr_t>(Smi::FromInt(0)); |
| 1926 bool is_native = value_type == TRANSLATED_VALUE_IS_NATIVE; | 1917 bool is_native = value_type == TRANSLATED_VALUE_IS_NATIVE; |
| 1927 | 1918 |
| 1928 // Ignore commands marked as duplicate and act on the first non-duplicate. | |
| 1929 Translation::Opcode opcode = | 1919 Translation::Opcode opcode = |
| 1930 static_cast<Translation::Opcode>(iterator->Next()); | 1920 static_cast<Translation::Opcode>(iterator->Next()); |
| 1931 while (opcode == Translation::DUPLICATE) { | |
| 1932 opcode = static_cast<Translation::Opcode>(iterator->Next()); | |
| 1933 iterator->Skip(Translation::NumberOfOperandsFor(opcode)); | |
| 1934 opcode = static_cast<Translation::Opcode>(iterator->Next()); | |
| 1935 } | |
| 1936 | 1921 |
| 1937 switch (opcode) { | 1922 switch (opcode) { |
| 1938 case Translation::BEGIN: | 1923 case Translation::BEGIN: |
| 1939 case Translation::JS_FRAME: | 1924 case Translation::JS_FRAME: |
| 1940 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 1925 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
| 1941 case Translation::CONSTRUCT_STUB_FRAME: | 1926 case Translation::CONSTRUCT_STUB_FRAME: |
| 1942 case Translation::GETTER_STUB_FRAME: | 1927 case Translation::GETTER_STUB_FRAME: |
| 1943 case Translation::SETTER_STUB_FRAME: | 1928 case Translation::SETTER_STUB_FRAME: |
| 1944 case Translation::COMPILED_STUB_FRAME: | 1929 case Translation::COMPILED_STUB_FRAME: |
| 1945 case Translation::DUPLICATE: | |
| 1946 UNREACHABLE(); | 1930 UNREACHABLE(); |
| 1947 return; | 1931 return; |
| 1948 | 1932 |
| 1949 case Translation::REGISTER: { | 1933 case Translation::REGISTER: { |
| 1950 int input_reg = iterator->Next(); | 1934 int input_reg = iterator->Next(); |
| 1951 intptr_t input_value = input_->GetRegister(input_reg); | 1935 intptr_t input_value = input_->GetRegister(input_reg); |
| 1952 if (trace_) { | 1936 if (trace_) { |
| 1953 PrintF( | 1937 PrintF( |
| 1954 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", | 1938 " 0x%08" V8PRIxPTR ": [top + %d] <- 0x%08" V8PRIxPTR " ; %s ", |
| 1955 output_[frame_index]->GetTop() + output_offset, | 1939 output_[frame_index]->GetTop() + output_offset, |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2189 disasm::NameConverter converter; | 2173 disasm::NameConverter converter; |
| 2190 FrameDescription* output = output_[0]; | 2174 FrameDescription* output = output_[0]; |
| 2191 | 2175 |
| 2192 // The input values are all part of the unoptimized frame so they | 2176 // The input values are all part of the unoptimized frame so they |
| 2193 // are all tagged pointers. | 2177 // are all tagged pointers. |
| 2194 uintptr_t input_value = input_->GetFrameSlot(*input_offset); | 2178 uintptr_t input_value = input_->GetFrameSlot(*input_offset); |
| 2195 Object* input_object = reinterpret_cast<Object*>(input_value); | 2179 Object* input_object = reinterpret_cast<Object*>(input_value); |
| 2196 | 2180 |
| 2197 Translation::Opcode opcode = | 2181 Translation::Opcode opcode = |
| 2198 static_cast<Translation::Opcode>(iterator->Next()); | 2182 static_cast<Translation::Opcode>(iterator->Next()); |
| 2199 bool duplicate = (opcode == Translation::DUPLICATE); | |
| 2200 if (duplicate) { | |
| 2201 opcode = static_cast<Translation::Opcode>(iterator->Next()); | |
| 2202 } | |
| 2203 | 2183 |
| 2204 switch (opcode) { | 2184 switch (opcode) { |
| 2205 case Translation::BEGIN: | 2185 case Translation::BEGIN: |
| 2206 case Translation::JS_FRAME: | 2186 case Translation::JS_FRAME: |
| 2207 case Translation::ARGUMENTS_ADAPTOR_FRAME: | 2187 case Translation::ARGUMENTS_ADAPTOR_FRAME: |
| 2208 case Translation::CONSTRUCT_STUB_FRAME: | 2188 case Translation::CONSTRUCT_STUB_FRAME: |
| 2209 case Translation::GETTER_STUB_FRAME: | 2189 case Translation::GETTER_STUB_FRAME: |
| 2210 case Translation::SETTER_STUB_FRAME: | 2190 case Translation::SETTER_STUB_FRAME: |
| 2211 case Translation::COMPILED_STUB_FRAME: | 2191 case Translation::COMPILED_STUB_FRAME: |
| 2212 case Translation::DUPLICATE: | |
| 2213 UNREACHABLE(); // Malformed input. | 2192 UNREACHABLE(); // Malformed input. |
| 2214 return false; | 2193 return false; |
| 2215 | 2194 |
| 2216 case Translation::REGISTER: { | 2195 case Translation::REGISTER: { |
| 2217 int output_reg = iterator->Next(); | 2196 int output_reg = iterator->Next(); |
| 2218 if (FLAG_trace_osr) { | 2197 if (FLAG_trace_osr) { |
| 2219 PrintF(" %s <- 0x%08" V8PRIxPTR " ; [sp + %d]\n", | 2198 PrintF(" %s <- 0x%08" V8PRIxPTR " ; [sp + %d]\n", |
| 2220 converter.NameOfCPURegister(output_reg), | 2199 converter.NameOfCPURegister(output_reg), |
| 2221 input_value, | 2200 input_value, |
| 2222 *input_offset); | 2201 *input_offset); |
| 2223 } | 2202 } |
| 2224 output->SetRegister(output_reg, input_value); | 2203 output->SetRegister(output_reg, input_value); |
| 2225 break; | 2204 break; |
| 2226 } | 2205 } |
| 2227 | 2206 |
| 2228 case Translation::INT32_REGISTER: { | 2207 case Translation::INT32_REGISTER: { |
| 2229 int32_t int32_value = 0; | 2208 int32_t int32_value = 0; |
| 2230 if (!input_object->ToInt32(&int32_value)) return false; | 2209 if (!input_object->ToInt32(&int32_value)) return false; |
| 2231 | 2210 |
| 2232 int output_reg = iterator->Next(); | 2211 int output_reg = iterator->Next(); |
| 2233 if (FLAG_trace_osr) { | 2212 if (FLAG_trace_osr) { |
| 2234 PrintF(" %s <- %d (int32) ; [sp + %d]\n", | 2213 PrintF(" %s <- %d (int32) ; [sp + %d]\n", |
| 2235 converter.NameOfCPURegister(output_reg), | 2214 converter.NameOfCPURegister(output_reg), |
| 2236 int32_value, | 2215 int32_value, |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2361 case Translation::ARGUMENTS_OBJECT: { | 2340 case Translation::ARGUMENTS_OBJECT: { |
| 2362 // Optimized code assumes that the argument object has not been | 2341 // Optimized code assumes that the argument object has not been |
| 2363 // materialized and so bypasses it when doing arguments access. | 2342 // materialized and so bypasses it when doing arguments access. |
| 2364 // We should have bailed out before starting the frame | 2343 // We should have bailed out before starting the frame |
| 2365 // translation. | 2344 // translation. |
| 2366 UNREACHABLE(); | 2345 UNREACHABLE(); |
| 2367 return false; | 2346 return false; |
| 2368 } | 2347 } |
| 2369 } | 2348 } |
| 2370 | 2349 |
| 2371 if (!duplicate) *input_offset -= kPointerSize; | 2350 *input_offset -= kPointerSize; |
| 2372 return true; | 2351 return true; |
| 2373 } | 2352 } |
| 2374 | 2353 |
| 2375 | 2354 |
| 2376 void Deoptimizer::PatchInterruptCode(Code* unoptimized_code, | 2355 void Deoptimizer::PatchInterruptCode(Code* unoptimized_code, |
| 2377 Code* interrupt_code, | 2356 Code* interrupt_code, |
| 2378 Code* replacement_code) { | 2357 Code* replacement_code) { |
| 2379 // Iterate over the back edge table and patch every interrupt | 2358 // Iterate over the back edge table and patch every interrupt |
| 2380 // call to an unconditional call to the replacement code. | 2359 // call to an unconditional call to the replacement code. |
| 2381 ASSERT(unoptimized_code->kind() == Code::FUNCTION); | 2360 ASSERT(unoptimized_code->kind() == Code::FUNCTION); |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2818 buffer_->Add(index, zone()); | 2797 buffer_->Add(index, zone()); |
| 2819 } | 2798 } |
| 2820 | 2799 |
| 2821 | 2800 |
| 2822 void Translation::StoreLiteral(int literal_id) { | 2801 void Translation::StoreLiteral(int literal_id) { |
| 2823 buffer_->Add(LITERAL, zone()); | 2802 buffer_->Add(LITERAL, zone()); |
| 2824 buffer_->Add(literal_id, zone()); | 2803 buffer_->Add(literal_id, zone()); |
| 2825 } | 2804 } |
| 2826 | 2805 |
| 2827 | 2806 |
| 2828 void Translation::MarkDuplicate() { | 2807 void Translation::StoreArgumentsObject(bool args_known, |
| 2829 buffer_->Add(DUPLICATE, zone()); | 2808 int args_index, |
| 2809 int args_length) { |
| 2810 buffer_->Add(ARGUMENTS_OBJECT, zone()); |
| 2811 buffer_->Add(args_known, zone()); |
| 2812 buffer_->Add(args_index, zone()); |
| 2813 buffer_->Add(args_length, zone()); |
| 2830 } | 2814 } |
| 2831 | 2815 |
| 2832 | 2816 |
| 2833 int Translation::NumberOfOperandsFor(Opcode opcode) { | 2817 int Translation::NumberOfOperandsFor(Opcode opcode) { |
| 2834 switch (opcode) { | 2818 switch (opcode) { |
| 2835 case DUPLICATE: | |
| 2836 return 0; | |
| 2837 case GETTER_STUB_FRAME: | 2819 case GETTER_STUB_FRAME: |
| 2838 case SETTER_STUB_FRAME: | 2820 case SETTER_STUB_FRAME: |
| 2839 case ARGUMENTS_OBJECT: | 2821 case ARGUMENTS_OBJECT: |
| 2840 case REGISTER: | 2822 case REGISTER: |
| 2841 case INT32_REGISTER: | 2823 case INT32_REGISTER: |
| 2842 case UINT32_REGISTER: | 2824 case UINT32_REGISTER: |
| 2843 case DOUBLE_REGISTER: | 2825 case DOUBLE_REGISTER: |
| 2844 case STACK_SLOT: | 2826 case STACK_SLOT: |
| 2845 case INT32_STACK_SLOT: | 2827 case INT32_STACK_SLOT: |
| 2846 case UINT32_STACK_SLOT: | 2828 case UINT32_STACK_SLOT: |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2891 case INT32_STACK_SLOT: | 2873 case INT32_STACK_SLOT: |
| 2892 return "INT32_STACK_SLOT"; | 2874 return "INT32_STACK_SLOT"; |
| 2893 case UINT32_STACK_SLOT: | 2875 case UINT32_STACK_SLOT: |
| 2894 return "UINT32_STACK_SLOT"; | 2876 return "UINT32_STACK_SLOT"; |
| 2895 case DOUBLE_STACK_SLOT: | 2877 case DOUBLE_STACK_SLOT: |
| 2896 return "DOUBLE_STACK_SLOT"; | 2878 return "DOUBLE_STACK_SLOT"; |
| 2897 case LITERAL: | 2879 case LITERAL: |
| 2898 return "LITERAL"; | 2880 return "LITERAL"; |
| 2899 case ARGUMENTS_OBJECT: | 2881 case ARGUMENTS_OBJECT: |
| 2900 return "ARGUMENTS_OBJECT"; | 2882 return "ARGUMENTS_OBJECT"; |
| 2901 case DUPLICATE: | |
| 2902 return "DUPLICATE"; | |
| 2903 } | 2883 } |
| 2904 UNREACHABLE(); | 2884 UNREACHABLE(); |
| 2905 return ""; | 2885 return ""; |
| 2906 } | 2886 } |
| 2907 | 2887 |
| 2908 #endif | 2888 #endif |
| 2909 | 2889 |
| 2910 | 2890 |
| 2911 DeoptimizingCodeListNode::DeoptimizingCodeListNode(Code* code): next_(NULL) { | 2891 DeoptimizingCodeListNode::DeoptimizingCodeListNode(Code* code): next_(NULL) { |
| 2912 GlobalHandles* global_handles = code->GetIsolate()->global_handles(); | 2892 GlobalHandles* global_handles = code->GetIsolate()->global_handles(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2944 break; | 2924 break; |
| 2945 | 2925 |
| 2946 case Translation::ARGUMENTS_OBJECT: | 2926 case Translation::ARGUMENTS_OBJECT: |
| 2947 // This can be only emitted for local slots not for argument slots. | 2927 // This can be only emitted for local slots not for argument slots. |
| 2948 break; | 2928 break; |
| 2949 | 2929 |
| 2950 case Translation::REGISTER: | 2930 case Translation::REGISTER: |
| 2951 case Translation::INT32_REGISTER: | 2931 case Translation::INT32_REGISTER: |
| 2952 case Translation::UINT32_REGISTER: | 2932 case Translation::UINT32_REGISTER: |
| 2953 case Translation::DOUBLE_REGISTER: | 2933 case Translation::DOUBLE_REGISTER: |
| 2954 case Translation::DUPLICATE: | |
| 2955 // We are at safepoint which corresponds to call. All registers are | 2934 // We are at safepoint which corresponds to call. All registers are |
| 2956 // saved by caller so there would be no live registers at this | 2935 // saved by caller so there would be no live registers at this |
| 2957 // point. Thus these translation commands should not be used. | 2936 // point. Thus these translation commands should not be used. |
| 2958 break; | 2937 break; |
| 2959 | 2938 |
| 2960 case Translation::STACK_SLOT: { | 2939 case Translation::STACK_SLOT: { |
| 2961 int slot_index = iterator->Next(); | 2940 int slot_index = iterator->Next(); |
| 2962 Address slot_addr = SlotAddress(frame, slot_index); | 2941 Address slot_addr = SlotAddress(frame, slot_index); |
| 2963 return SlotRef(slot_addr, SlotRef::TAGGED); | 2942 return SlotRef(slot_addr, SlotRef::TAGGED); |
| 2964 } | 2943 } |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3113 | 3092 |
| 3114 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { | 3093 void DeoptimizedFrameInfo::Iterate(ObjectVisitor* v) { |
| 3115 v->VisitPointer(BitCast<Object**>(&function_)); | 3094 v->VisitPointer(BitCast<Object**>(&function_)); |
| 3116 v->VisitPointers(parameters_, parameters_ + parameters_count_); | 3095 v->VisitPointers(parameters_, parameters_ + parameters_count_); |
| 3117 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); | 3096 v->VisitPointers(expression_stack_, expression_stack_ + expression_count_); |
| 3118 } | 3097 } |
| 3119 | 3098 |
| 3120 #endif // ENABLE_DEBUGGER_SUPPORT | 3099 #endif // ENABLE_DEBUGGER_SUPPORT |
| 3121 | 3100 |
| 3122 } } // namespace v8::internal | 3101 } } // namespace v8::internal |
| OLD | NEW |