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

Side by Side Diff: src/ia32/macro-assembler-ia32.cc

Issue 3792003: Optimizing HandleScope. Also fixed HandleScope destruction when API getter th... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 2 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
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 } 1068 }
1069 1069
1070 1070
1071 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, 1071 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
1072 int num_arguments, 1072 int num_arguments,
1073 int result_size) { 1073 int result_size) {
1074 TailCallExternalReference(ExternalReference(fid), num_arguments, result_size); 1074 TailCallExternalReference(ExternalReference(fid), num_arguments, result_size);
1075 } 1075 }
1076 1076
1077 1077
1078 void MacroAssembler::PushHandleScope(Register scratch) { 1078 // If true, a Handle<T> passed by value is passed and returned by
1079 // Push the number of extensions, smi-tagged so the gc will ignore it. 1079 // using the location_ field directly. If false, it is passed and
1080 ExternalReference extensions_address = 1080 // returned as a pointer to a handle.
1081 ExternalReference::handle_scope_extensions_address(); 1081 #ifdef USING_BSD_ABI
1082 mov(scratch, Operand::StaticVariable(extensions_address)); 1082 static const bool kPassHandlesDirectly = true;
1083 SmiTag(scratch); 1083 #else
1084 push(scratch); 1084 static const bool kPassHandlesDirectly = false;
1085 mov(Operand::StaticVariable(extensions_address), Immediate(0)); 1085 #endif
1086 // Push next and limit pointers which will be wordsize aligned and 1086
1087 // hence automatically smi tagged. 1087
1088 ExternalReference next_address = 1088 Operand ApiParameterOperand(int index) {
1089 ExternalReference::handle_scope_next_address(); 1089 return Operand(esp, (index + (kPassHandlesDirectly ? 0 : 1)) * kPointerSize);
1090 push(Operand::StaticVariable(next_address));
1091 ExternalReference limit_address =
1092 ExternalReference::handle_scope_limit_address();
1093 push(Operand::StaticVariable(limit_address));
1094 } 1090 }
1095 1091
1096 1092
1097 Object* MacroAssembler::PopHandleScopeHelper(Register saved, 1093 void MacroAssembler::PrepareCallApiFunction(int stack_space, int argc) {
1098 Register scratch, 1094 if (kPassHandlesDirectly) {
1099 bool gc_allowed) { 1095 EnterApiExitFrame(stack_space, argc);
1100 Object* result = NULL; 1096 // When handles as passed directly we don't have to allocate extra
1101 ExternalReference extensions_address = 1097 // space for and pass an out parameter.
1102 ExternalReference::handle_scope_extensions_address();
1103 Label write_back;
1104 mov(scratch, Operand::StaticVariable(extensions_address));
1105 cmp(Operand(scratch), Immediate(0));
1106 j(equal, &write_back);
1107 push(saved);
1108 if (gc_allowed) {
1109 CallRuntime(Runtime::kDeleteHandleScopeExtensions, 0);
1110 } else { 1098 } else {
1111 result = TryCallRuntime(Runtime::kDeleteHandleScopeExtensions, 0); 1099 // We allocate two additional slots: return value and pointer to it.
1112 if (result->IsFailure()) return result; 1100 EnterApiExitFrame(stack_space, argc + 2);
1113 } 1101 }
1114 pop(saved);
1115
1116 bind(&write_back);
1117 ExternalReference limit_address =
1118 ExternalReference::handle_scope_limit_address();
1119 pop(Operand::StaticVariable(limit_address));
1120 ExternalReference next_address =
1121 ExternalReference::handle_scope_next_address();
1122 pop(Operand::StaticVariable(next_address));
1123 pop(scratch);
1124 SmiUntag(scratch);
1125 mov(Operand::StaticVariable(extensions_address), scratch);
1126
1127 return result;
1128 } 1102 }
1129 1103
1130 1104
1131 void MacroAssembler::PopHandleScope(Register saved, Register scratch) { 1105 void MacroAssembler::CallApiFunctionAndReturn(ApiFunction* function, int argc) {
1132 PopHandleScopeHelper(saved, scratch, true); 1106 if (!kPassHandlesDirectly) {
1107 // The argument slots are filled as follows:
1108 //
1109 // n + 1: output cell
1110 // n: arg n
1111 // ...
1112 // 1: arg1
1113 // 0: pointer to the output cell
1114 //
1115 // Note that this is one more "argument" than the function expects
1116 // so the out cell will have to be popped explicitly after returning
1117 // from the function. The out cell contains Handle.
1118 lea(eax, Operand(esp, (argc + 1) * kPointerSize)); // pointer to out cell.
1119 mov(Operand(esp, 0 * kPointerSize), eax); // output.
1120 mov(Operand(esp, (argc + 1) * kPointerSize), Immediate(0)); // out cell.
1121 }
1122
1123 ExternalReference next_address =
1124 ExternalReference::handle_scope_next_address();
1125 ExternalReference limit_address =
1126 ExternalReference::handle_scope_limit_address();
1127 ExternalReference level_address =
1128 ExternalReference::handle_scope_level_address();
1129
1130 // Allocate HandleScope in callee-save registers.
1131 mov(ebx, Operand::StaticVariable(next_address));
1132 mov(edi, Operand::StaticVariable(limit_address));
1133 add(Operand::StaticVariable(level_address), Immediate(1));
1134
1135 // Call the api function!
1136 call(function->address(), RelocInfo::RUNTIME_ENTRY);
1137
1138 if (!kPassHandlesDirectly) {
1139 // The returned value is a pointer to the handle holding the result.
1140 // Dereference this to get to the location.
1141 mov(eax, Operand(eax, 0));
1142 }
1143
1144 Label empty_handle;
1145 Label prologue;
1146 Label promote_scheduled_exception;
1147 Label delete_allocated_handles;
1148 Label leave_exit_frame;
1149
1150 // Check if the result handle holds 0.
1151 test(eax, Operand(eax));
1152 j(zero, &empty_handle, not_taken);
1153 // It was non-zero. Dereference to get the result value.
1154 mov(eax, Operand(eax, 0));
1155 bind(&prologue);
1156 // No more valid handles (the result handle was the last one). Restore
1157 // previous handle scope.
1158 mov(Operand::StaticVariable(next_address), ebx);
1159 sub(Operand::StaticVariable(level_address), Immediate(1));
1160 Assert(above_equal, "Invalid HandleScope level");
1161 cmp(edi, Operand::StaticVariable(limit_address));
1162 j(not_equal, &delete_allocated_handles, not_taken);
1163 bind(&leave_exit_frame);
1164
1165 // Check if the function scheduled an exception.
1166 ExternalReference scheduled_exception_address =
1167 ExternalReference::scheduled_exception_address();
1168 cmp(Operand::StaticVariable(scheduled_exception_address),
1169 Immediate(Factory::the_hole_value()));
1170 j(not_equal, &promote_scheduled_exception, not_taken);
1171 LeaveExitFrame();
1172 ret(0);
1173 bind(&promote_scheduled_exception);
1174 TailCallRuntime(Runtime::kPromoteScheduledException, 0, 1);
1175 bind(&empty_handle);
1176 // It was zero; the result is undefined.
1177 mov(eax, Factory::undefined_value());
1178 jmp(&prologue);
1179
1180 // HandleScope limit has changed. Delete allocated extensions.
1181 bind(&delete_allocated_handles);
1182 mov(Operand::StaticVariable(limit_address), edi);
1183 mov(edi, eax);
1184 mov(eax, Immediate(ExternalReference::delete_handle_scope_extensions()));
1185 call(Operand(eax));
1186 mov(eax, edi);
1187 jmp(&leave_exit_frame);
1133 } 1188 }
1134 1189
1135 1190
1136 Object* MacroAssembler::TryPopHandleScope(Register saved, Register scratch) {
1137 return PopHandleScopeHelper(saved, scratch, false);
1138 }
1139
1140
1141 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext) { 1191 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext) {
1142 // Set the entry point and jump to the C entry runtime stub. 1192 // Set the entry point and jump to the C entry runtime stub.
1143 mov(ebx, Immediate(ext)); 1193 mov(ebx, Immediate(ext));
1144 CEntryStub ces(1); 1194 CEntryStub ces(1);
1145 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); 1195 jmp(ces.GetCode(), RelocInfo::CODE_TARGET);
1146 } 1196 }
1147 1197
1148 1198
1149 void MacroAssembler::InvokePrologue(const ParameterCount& expected, 1199 void MacroAssembler::InvokePrologue(const ParameterCount& expected,
1150 const ParameterCount& actual, 1200 const ParameterCount& actual,
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after
1672 1722
1673 // Check that the code was patched as expected. 1723 // Check that the code was patched as expected.
1674 ASSERT(masm_.pc_ == address_ + size_); 1724 ASSERT(masm_.pc_ == address_ + size_);
1675 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 1725 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
1676 } 1726 }
1677 1727
1678 1728
1679 } } // namespace v8::internal 1729 } } // namespace v8::internal
1680 1730
1681 #endif // V8_TARGET_ARCH_IA32 1731 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/ia32/stub-cache-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698