| 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 | 
|---|