| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 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 11 matching lines...) Expand all Loading... |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "codegen-inl.h" | 30 #include "codegen-inl.h" |
| 31 #include "fast-codegen.h" | 31 #include "fast-codegen.h" |
| 32 #include "stub-cache.h" |
| 33 #include "debug.h" |
| 32 | 34 |
| 33 namespace v8 { | 35 namespace v8 { |
| 34 namespace internal { | 36 namespace internal { |
| 35 | 37 |
| 36 Handle<Code> FastCodeGenerator::MakeCode(FunctionLiteral* fun, | 38 Handle<Code> FastCodeGenerator::MakeCode(FunctionLiteral* fun, |
| 37 Handle<Script> script) { | 39 Handle<Script> script, |
| 40 bool is_eval) { |
| 38 CodeGenerator::MakeCodePrologue(fun); | 41 CodeGenerator::MakeCodePrologue(fun); |
| 39 const int kInitialBufferSize = 4 * KB; | 42 const int kInitialBufferSize = 4 * KB; |
| 40 MacroAssembler masm(NULL, kInitialBufferSize); | 43 MacroAssembler masm(NULL, kInitialBufferSize); |
| 41 FastCodeGenerator cgen(&masm); | 44 FastCodeGenerator cgen(&masm, script, is_eval); |
| 42 cgen.Generate(fun); | 45 cgen.Generate(fun); |
| 43 if (cgen.HasStackOverflow()) { | 46 if (cgen.HasStackOverflow()) { |
| 44 ASSERT(!Top::has_pending_exception()); | 47 ASSERT(!Top::has_pending_exception()); |
| 45 return Handle<Code>::null(); | 48 return Handle<Code>::null(); |
| 46 } | 49 } |
| 47 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP); | 50 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP); |
| 48 return CodeGenerator::MakeCodeEpilogue(fun, &masm, flags, script); | 51 return CodeGenerator::MakeCodeEpilogue(fun, &masm, flags, script); |
| 49 } | 52 } |
| 50 | 53 |
| 51 | 54 |
| 52 int FastCodeGenerator::SlotOffset(Slot* slot) { | 55 int FastCodeGenerator::SlotOffset(Slot* slot) { |
| 53 // Offset is negative because higher indexes are at lower addresses. | 56 // Offset is negative because higher indexes are at lower addresses. |
| 54 int offset = -slot->index() * kPointerSize; | 57 int offset = -slot->index() * kPointerSize; |
| 55 // Adjust by a (parameter or local) base offset. | 58 // Adjust by a (parameter or local) base offset. |
| 56 switch (slot->type()) { | 59 switch (slot->type()) { |
| 57 case Slot::PARAMETER: | 60 case Slot::PARAMETER: |
| 58 offset += (function_->scope()->num_parameters() + 1) * kPointerSize; | 61 offset += (function_->scope()->num_parameters() + 1) * kPointerSize; |
| 59 break; | 62 break; |
| 60 case Slot::LOCAL: | 63 case Slot::LOCAL: |
| 61 offset += JavaScriptFrameConstants::kLocal0Offset; | 64 offset += JavaScriptFrameConstants::kLocal0Offset; |
| 62 break; | 65 break; |
| 63 default: | 66 default: |
| 64 UNREACHABLE(); | 67 UNREACHABLE(); |
| 65 } | 68 } |
| 66 return offset; | 69 return offset; |
| 67 } | 70 } |
| 68 | 71 |
| 72 |
| 73 void FastCodeGenerator::VisitDeclarations( |
| 74 ZoneList<Declaration*>* declarations) { |
| 75 int length = declarations->length(); |
| 76 int globals = 0; |
| 77 for (int i = 0; i < length; i++) { |
| 78 Declaration* node = declarations->at(i); |
| 79 Variable* var = node->proxy()->var(); |
| 80 Slot* slot = var->slot(); |
| 81 |
| 82 // If it was not possible to allocate the variable at compile |
| 83 // time, we need to "declare" it at runtime to make sure it |
| 84 // actually exists in the local context. |
| 85 if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) { |
| 86 UNREACHABLE(); |
| 87 } else { |
| 88 // Count global variables and functions for later processing |
| 89 globals++; |
| 90 } |
| 91 } |
| 92 |
| 93 // Return in case of no declared global functions or variables. |
| 94 if (globals == 0) return; |
| 95 |
| 96 // Compute array of global variable and function declarations. |
| 97 Handle<FixedArray> array = Factory::NewFixedArray(2 * globals, TENURED); |
| 98 for (int j = 0, i = 0; i < length; i++) { |
| 99 Declaration* node = declarations->at(i); |
| 100 Variable* var = node->proxy()->var(); |
| 101 Slot* slot = var->slot(); |
| 102 |
| 103 if ((slot == NULL || slot->type() != Slot::LOOKUP) && var->is_global()) { |
| 104 array->set(j++, *(var->name())); |
| 105 if (node->fun() == NULL) { |
| 106 if (var->mode() == Variable::CONST) { |
| 107 // In case this is const property use the hole. |
| 108 array->set_the_hole(j++); |
| 109 } else { |
| 110 array->set_undefined(j++); |
| 111 } |
| 112 } else { |
| 113 Handle<JSFunction> function = BuildBoilerplate(node->fun()); |
| 114 // Check for stack-overflow exception. |
| 115 if (HasStackOverflow()) return; |
| 116 array->set(j++, *function); |
| 117 } |
| 118 } |
| 119 } |
| 120 |
| 121 // Invoke the platform-dependent code generator to do the actual |
| 122 // declaration the global variables and functions. |
| 123 DeclareGlobals(array); |
| 124 } |
| 125 |
| 126 Handle<JSFunction> FastCodeGenerator::BuildBoilerplate(FunctionLiteral* fun) { |
| 127 #ifdef DEBUG |
| 128 // We should not try to compile the same function literal more than |
| 129 // once. |
| 130 fun->mark_as_compiled(); |
| 131 #endif |
| 132 |
| 133 // Generate code |
| 134 Handle<Code> code = CodeGenerator::ComputeLazyCompile(fun->num_parameters()); |
| 135 // Check for stack-overflow exception. |
| 136 if (code.is_null()) { |
| 137 SetStackOverflow(); |
| 138 return Handle<JSFunction>::null(); |
| 139 } |
| 140 |
| 141 // Create a boilerplate function. |
| 142 Handle<JSFunction> function = |
| 143 Factory::NewFunctionBoilerplate(fun->name(), |
| 144 fun->materialized_literal_count(), |
| 145 code); |
| 146 CodeGenerator::SetFunctionInfo(function, fun, false, script_); |
| 147 |
| 148 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 149 // Notify debugger that a new function has been added. |
| 150 Debugger::OnNewFunction(function); |
| 151 #endif |
| 152 |
| 153 // Set the expected number of properties for instances and return |
| 154 // the resulting function. |
| 155 SetExpectedNofPropertiesFromEstimate(function, |
| 156 fun->expected_property_count()); |
| 157 return function; |
| 158 } |
| 159 |
| 160 |
| 69 void FastCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { | 161 void FastCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { |
| 70 if (FLAG_debug_info) { | 162 if (FLAG_debug_info) { |
| 71 CodeGenerator::RecordPositions(masm_, fun->start_position()); | 163 CodeGenerator::RecordPositions(masm_, fun->start_position()); |
| 72 } | 164 } |
| 73 } | 165 } |
| 74 | 166 |
| 75 | 167 |
| 76 void FastCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { | 168 void FastCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { |
| 77 if (FLAG_debug_info) { | 169 if (FLAG_debug_info) { |
| 78 CodeGenerator::RecordPositions(masm_, fun->end_position()); | 170 CodeGenerator::RecordPositions(masm_, fun->end_position()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 92 masm_->RecordPosition(pos); | 184 masm_->RecordPosition(pos); |
| 93 } | 185 } |
| 94 } | 186 } |
| 95 | 187 |
| 96 | 188 |
| 97 void FastCodeGenerator::VisitDeclaration(Declaration* decl) { | 189 void FastCodeGenerator::VisitDeclaration(Declaration* decl) { |
| 98 UNREACHABLE(); | 190 UNREACHABLE(); |
| 99 } | 191 } |
| 100 | 192 |
| 101 | 193 |
| 102 void FastCodeGenerator::VisitBlock(Block* stmt) { | |
| 103 UNREACHABLE(); | |
| 104 } | |
| 105 | |
| 106 | |
| 107 void FastCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { | 194 void FastCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { |
| 108 UNREACHABLE(); | 195 UNREACHABLE(); |
| 109 } | 196 } |
| 110 | 197 |
| 111 | 198 |
| 112 void FastCodeGenerator::VisitIfStatement(IfStatement* stmt) { | 199 void FastCodeGenerator::VisitIfStatement(IfStatement* stmt) { |
| 113 UNREACHABLE(); | 200 UNREACHABLE(); |
| 114 } | 201 } |
| 115 | 202 |
| 116 | 203 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 void FastCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 254 void FastCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { |
| 168 UNREACHABLE(); | 255 UNREACHABLE(); |
| 169 } | 256 } |
| 170 | 257 |
| 171 | 258 |
| 172 void FastCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { | 259 void FastCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { |
| 173 UNREACHABLE(); | 260 UNREACHABLE(); |
| 174 } | 261 } |
| 175 | 262 |
| 176 | 263 |
| 177 void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { | |
| 178 UNREACHABLE(); | |
| 179 } | |
| 180 | |
| 181 | |
| 182 void FastCodeGenerator::VisitFunctionBoilerplateLiteral( | 264 void FastCodeGenerator::VisitFunctionBoilerplateLiteral( |
| 183 FunctionBoilerplateLiteral* expr) { | 265 FunctionBoilerplateLiteral* expr) { |
| 184 UNREACHABLE(); | 266 UNREACHABLE(); |
| 185 } | 267 } |
| 186 | 268 |
| 187 | 269 |
| 188 void FastCodeGenerator::VisitConditional(Conditional* expr) { | 270 void FastCodeGenerator::VisitConditional(Conditional* expr) { |
| 189 UNREACHABLE(); | 271 UNREACHABLE(); |
| 190 } | 272 } |
| 191 | 273 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 void FastCodeGenerator::VisitThrow(Throw* expr) { | 306 void FastCodeGenerator::VisitThrow(Throw* expr) { |
| 225 UNREACHABLE(); | 307 UNREACHABLE(); |
| 226 } | 308 } |
| 227 | 309 |
| 228 | 310 |
| 229 void FastCodeGenerator::VisitProperty(Property* expr) { | 311 void FastCodeGenerator::VisitProperty(Property* expr) { |
| 230 UNREACHABLE(); | 312 UNREACHABLE(); |
| 231 } | 313 } |
| 232 | 314 |
| 233 | 315 |
| 234 void FastCodeGenerator::VisitCall(Call* expr) { | |
| 235 UNREACHABLE(); | |
| 236 } | |
| 237 | |
| 238 | |
| 239 void FastCodeGenerator::VisitCallNew(CallNew* expr) { | 316 void FastCodeGenerator::VisitCallNew(CallNew* expr) { |
| 240 UNREACHABLE(); | 317 UNREACHABLE(); |
| 241 } | 318 } |
| 242 | 319 |
| 243 | 320 |
| 244 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | |
| 245 UNREACHABLE(); | |
| 246 } | |
| 247 | |
| 248 | |
| 249 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 321 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
| 250 UNREACHABLE(); | 322 UNREACHABLE(); |
| 251 } | 323 } |
| 252 | 324 |
| 253 | 325 |
| 254 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { | 326 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 255 UNREACHABLE(); | 327 UNREACHABLE(); |
| 256 } | 328 } |
| 257 | 329 |
| 258 | 330 |
| 259 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { | 331 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { |
| 260 UNREACHABLE(); | 332 UNREACHABLE(); |
| 261 } | 333 } |
| 262 | 334 |
| 263 | 335 |
| 264 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 336 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
| 265 UNREACHABLE(); | 337 UNREACHABLE(); |
| 266 } | 338 } |
| 267 | 339 |
| 268 | 340 |
| 269 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 341 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
| 270 UNREACHABLE(); | 342 UNREACHABLE(); |
| 271 } | 343 } |
| 272 | 344 |
| 273 | 345 |
| 274 } } // namespace v8::internal | 346 } } // namespace v8::internal |
| OLD | NEW |