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

Side by Side Diff: src/isolate.cc

Issue 1010883002: Switch full-codegen from StackHandlers to handler table. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@local_cleanup-isolate-dead-code
Patch Set: Minor cleanup. Created 5 years, 9 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdlib.h> 5 #include <stdlib.h>
6 6
7 #include <fstream> // NOLINT(readability/streams) 7 #include <fstream> // NOLINT(readability/streams)
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "src/v8.h" 10 #include "src/v8.h"
(...skipping 990 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 1001
1002 Object* Isolate::ReThrow(Object* exception) { 1002 Object* Isolate::ReThrow(Object* exception) {
1003 DCHECK(!has_pending_exception()); 1003 DCHECK(!has_pending_exception());
1004 1004
1005 // Set the exception being re-thrown. 1005 // Set the exception being re-thrown.
1006 set_pending_exception(exception); 1006 set_pending_exception(exception);
1007 return heap()->exception(); 1007 return heap()->exception();
1008 } 1008 }
1009 1009
1010 1010
1011 // TODO(turbofan): Make sure table is sorted and use binary search.
1012 static int LookupInHandlerTable(Code* code, int pc_offset) {
1013 FixedArray* handler_table = code->handler_table();
1014 for (int i = 0; i < handler_table->length(); i += 2) {
1015 int return_offset = Smi::cast(handler_table->get(i))->value();
1016 int handler_offset = Smi::cast(handler_table->get(i + 1))->value();
1017 if (pc_offset == return_offset) return handler_offset;
1018 }
1019 return -1;
1020 }
1021
1022
1023 Object* Isolate::FindHandler() { 1011 Object* Isolate::FindHandler() {
1024 Object* exception = pending_exception(); 1012 Object* exception = pending_exception();
1025 1013
1026 Code* code = nullptr; 1014 Code* code = nullptr;
1027 Context* context = nullptr; 1015 Context* context = nullptr;
1028 intptr_t offset = 0; 1016 intptr_t offset = 0;
1029 Address handler_sp = nullptr; 1017 Address handler_sp = nullptr;
1030 Address handler_fp = nullptr; 1018 Address handler_fp = nullptr;
1031 1019
1032 // Special handling of termination exceptions, uncatchable by JavaScript code, 1020 // Special handling of termination exceptions, uncatchable by JavaScript code,
1033 // we unwind the handlers until the top ENTRY handler is found. 1021 // we unwind the handlers until the top ENTRY handler is found.
1034 bool catchable_by_js = is_catchable_by_javascript(exception); 1022 bool catchable_by_js = is_catchable_by_javascript(exception);
1035 1023
1036 // Compute handler and stack unwinding information by performing a full walk 1024 // Compute handler and stack unwinding information by performing a full walk
1037 // over the stack and dispatching according to the frame type. 1025 // over the stack and dispatching according to the frame type.
1038 for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) { 1026 for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) {
1039 StackFrame* frame = iter.frame(); 1027 StackFrame* frame = iter.frame();
1040 1028
1041 // For JSEntryStub frames we always have a handler. 1029 // For JSEntryStub frames we always have a handler.
1042 if (frame->is_entry() || frame->is_entry_construct()) { 1030 if (frame->is_entry() || frame->is_entry_construct()) {
1043 StackHandler* handler = frame->top_handler(); 1031 StackHandler* handler = frame->top_handler();
1044 DCHECK_EQ(0, handler->index());
1045 1032
1046 // Restore the next handler. 1033 // Restore the next handler.
1047 thread_local_top()->handler_ = handler->next()->address(); 1034 thread_local_top()->handler_ = handler->next()->address();
1048 1035
1049 // Gather information from the handler. 1036 // Gather information from the handler.
1050 code = frame->LookupCode(); 1037 code = frame->LookupCode();
1051 handler_sp = handler->address() + StackHandlerConstants::kSize; 1038 handler_sp = handler->address() + StackHandlerConstants::kSize;
1052 offset = Smi::cast(code->handler_table()->get(0))->value(); 1039 offset = Smi::cast(code->handler_table()->get(0))->value();
1053 break; 1040 break;
1054 } 1041 }
1055 1042
1056 // For JavaScript frames which have a handler, we use the handler.
1057 if (frame->is_java_script() && catchable_by_js && frame->HasHandler()) {
1058 StackHandler* handler = frame->top_handler();
1059
1060 // Restore the next handler.
1061 thread_local_top()->handler_ = handler->next()->address();
1062
1063 // Gather information from the handler.
1064 code = frame->LookupCode();
1065 context = handler->context();
1066 offset = Smi::cast(code->handler_table()->get(handler->index()))->value();
1067 handler_sp = handler->address() + StackHandlerConstants::kSize;
1068 handler_fp = frame->fp();
1069 break;
1070 }
1071
1072 // For optimized frames we perform a lookup in the handler table. 1043 // For optimized frames we perform a lookup in the handler table.
1073 if (frame->is_optimized() && catchable_by_js) { 1044 if (frame->is_optimized() && catchable_by_js) {
1074 Code* frame_code = frame->LookupCode(); 1045 OptimizedFrame* js_frame = static_cast<OptimizedFrame*>(frame);
1075 DCHECK(frame_code->is_optimized_code()); 1046 int stack_slots = 0; // Will contain stack slot count of frame.
1076 int pc_offset = static_cast<int>(frame->pc() - frame_code->entry()); 1047 offset = js_frame->LookupExceptionHandlerInTable(&stack_slots);
1077 int handler_offset = LookupInHandlerTable(frame_code, pc_offset); 1048 if (offset < 0) continue;
1078 if (handler_offset < 0) continue;
1079 1049
1080 // Compute the stack pointer from the frame pointer. This ensures that 1050 // Compute the stack pointer from the frame pointer. This ensures that
1081 // argument slots on the stack are dropped as returning would. 1051 // argument slots on the stack are dropped as returning would.
1082 Address return_sp = frame->fp() - 1052 Address return_sp = frame->fp() -
1083 StandardFrameConstants::kFixedFrameSizeFromFp - 1053 StandardFrameConstants::kFixedFrameSizeFromFp -
1084 frame_code->stack_slots() * kPointerSize; 1054 stack_slots * kPointerSize;
1085 1055
1086 // Gather information from the frame. 1056 // Gather information from the frame.
1087 code = frame_code; 1057 code = frame->LookupCode();
1088 offset = handler_offset;
1089 handler_sp = return_sp; 1058 handler_sp = return_sp;
1090 handler_fp = frame->fp(); 1059 handler_fp = frame->fp();
1091 break; 1060 break;
1061 }
1062
1063 // For JavaScript frames we perform a range lookup in the handler table.
1064 if (frame->is_java_script() && catchable_by_js) {
1065 JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame);
1066 int stack_slots = 0; // Will contain operand stack depth of handler.
1067 offset = js_frame->LookupExceptionHandlerInTable(&stack_slots);
1068 if (offset < 0) continue;
1069
1070 // Compute the stack pointer from the frame pointer. This ensures that
1071 // operand stack slots are dropped for nested statements. Also restore
1072 // correct context for the handler which is pushed within the try-block.
1073 Address return_sp = frame->fp() -
1074 StandardFrameConstants::kFixedFrameSizeFromFp -
1075 stack_slots * kPointerSize;
1076 STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
1077 context = Context::cast(Memory::Object_at(return_sp - kPointerSize));
1078
1079 // Gather information from the frame.
1080 code = frame->LookupCode();
1081 handler_sp = return_sp;
1082 handler_fp = frame->fp();
1083 break;
1092 } 1084 }
1093 } 1085 }
1094 1086
1095 // Handler must exist. 1087 // Handler must exist.
1096 CHECK(code != nullptr); 1088 CHECK(code != nullptr);
1097 1089
1098 // Store information to be consumed by the CEntryStub. 1090 // Store information to be consumed by the CEntryStub.
1099 thread_local_top()->pending_handler_context_ = context; 1091 thread_local_top()->pending_handler_context_ = context;
1100 thread_local_top()->pending_handler_code_ = code; 1092 thread_local_top()->pending_handler_code_ = code;
1101 thread_local_top()->pending_handler_offset_ = offset; 1093 thread_local_top()->pending_handler_offset_ = offset;
1102 thread_local_top()->pending_handler_fp_ = handler_fp; 1094 thread_local_top()->pending_handler_fp_ = handler_fp;
1103 thread_local_top()->pending_handler_sp_ = handler_sp; 1095 thread_local_top()->pending_handler_sp_ = handler_sp;
1104 1096
1105 // Return and clear pending exception. 1097 // Return and clear pending exception.
1106 clear_pending_exception(); 1098 clear_pending_exception();
1107 return exception; 1099 return exception;
1108 } 1100 }
1109 1101
1110 1102
1111 // TODO(mstarzinger): We shouldn't need the exception object here. 1103 // TODO(mstarzinger): We shouldn't need the exception object here.
1112 bool Isolate::PredictWhetherExceptionIsCaught(Object* exception) { 1104 bool Isolate::PredictWhetherExceptionIsCaught(Object* exception) {
1113 if (IsExternalHandlerOnTop(exception)) return true; 1105 if (IsExternalHandlerOnTop(exception)) return true;
1114 1106
1115 // Search for a JavaScript handler by performing a full walk over the stack 1107 // Search for a JavaScript handler by performing a full walk over the stack.
1116 // and dispatching according to the frame type. 1108 for (JavaScriptFrameIterator iter(this); !iter.done(); iter.Advance()) {
1117 for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) { 1109 JavaScriptFrame* frame = iter.frame();
1118 StackFrame* frame = iter.frame(); 1110 int stack_slots = 0; // The computed stack slot count is not used.
1119 1111 if (frame->LookupExceptionHandlerInTable(&stack_slots) > 0) return true;
1120 // For JavaScript frames which have a handler, we use the handler.
1121 if (frame->is_java_script() && frame->HasHandler()) {
1122 return true;
1123 }
1124
1125 // For optimized frames we perform a lookup in the handler table.
1126 if (frame->is_optimized()) {
1127 Code* frame_code = frame->LookupCode();
1128 DCHECK(frame_code->is_optimized_code());
1129 int pc_offset = static_cast<int>(frame->pc() - frame_code->entry());
1130 int handler_offset = LookupInHandlerTable(frame_code, pc_offset);
1131 if (handler_offset < 0) continue;
1132 return true;
1133 }
1134 } 1112 }
1135 1113
1136 // Handler not found. 1114 // Handler not found.
1137 return false; 1115 return false;
1138 } 1116 }
1139 1117
1140 1118
1141 Object* Isolate::ThrowIllegalOperation() { 1119 Object* Isolate::ThrowIllegalOperation() {
1142 if (FLAG_stack_trace_on_illegal) PrintStack(stdout); 1120 if (FLAG_stack_trace_on_illegal) PrintStack(stdout);
1143 return Throw(heap()->illegal_access_string()); 1121 return Throw(heap()->illegal_access_string());
(...skipping 1478 matching lines...) Expand 10 before | Expand all | Expand 10 after
2622 if (prev_ && prev_->Intercept(flag)) return true; 2600 if (prev_ && prev_->Intercept(flag)) return true;
2623 // Then check whether this scope intercepts. 2601 // Then check whether this scope intercepts.
2624 if ((flag & intercept_mask_)) { 2602 if ((flag & intercept_mask_)) {
2625 intercepted_flags_ |= flag; 2603 intercepted_flags_ |= flag;
2626 return true; 2604 return true;
2627 } 2605 }
2628 return false; 2606 return false;
2629 } 2607 }
2630 2608
2631 } } // namespace v8::internal 2609 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698