| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 | 54 |
| 55 Comment::~Comment() { | 55 Comment::~Comment() { |
| 56 if (msg_[0] == '[') __ RecordComment("]"); | 56 if (msg_[0] == '[') __ RecordComment("]"); |
| 57 } | 57 } |
| 58 | 58 |
| 59 #endif // DEBUG | 59 #endif // DEBUG |
| 60 | 60 |
| 61 #undef __ | 61 #undef __ |
| 62 | 62 |
| 63 | 63 |
| 64 CodeGenerator* CodeGeneratorScope::top_ = NULL; | |
| 65 | |
| 66 | |
| 67 void CodeGenerator::ProcessDeferred() { | 64 void CodeGenerator::ProcessDeferred() { |
| 68 while (!deferred_.is_empty()) { | 65 while (!deferred_.is_empty()) { |
| 69 DeferredCode* code = deferred_.RemoveLast(); | 66 DeferredCode* code = deferred_.RemoveLast(); |
| 70 ASSERT(masm_ == code->masm()); | 67 ASSERT(masm_ == code->masm()); |
| 71 // Record position of deferred code stub. | 68 // Record position of deferred code stub. |
| 72 masm_->positions_recorder()->RecordStatementPosition( | 69 masm_->positions_recorder()->RecordStatementPosition( |
| 73 code->statement_position()); | 70 code->statement_position()); |
| 74 if (code->position() != RelocInfo::kNoPosition) { | 71 if (code->position() != RelocInfo::kNoPosition) { |
| 75 masm_->positions_recorder()->RecordPosition(code->position()); | 72 masm_->positions_recorder()->RecordPosition(code->position()); |
| 76 } | 73 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 } | 119 } |
| 123 | 120 |
| 124 | 121 |
| 125 void CodeGenerator::MakeCodePrologue(CompilationInfo* info) { | 122 void CodeGenerator::MakeCodePrologue(CompilationInfo* info) { |
| 126 #ifdef DEBUG | 123 #ifdef DEBUG |
| 127 bool print_source = false; | 124 bool print_source = false; |
| 128 bool print_ast = false; | 125 bool print_ast = false; |
| 129 bool print_json_ast = false; | 126 bool print_json_ast = false; |
| 130 const char* ftype; | 127 const char* ftype; |
| 131 | 128 |
| 132 if (Bootstrapper::IsActive()) { | 129 if (Isolate::Current()->bootstrapper()->IsActive()) { |
| 133 print_source = FLAG_print_builtin_source; | 130 print_source = FLAG_print_builtin_source; |
| 134 print_ast = FLAG_print_builtin_ast; | 131 print_ast = FLAG_print_builtin_ast; |
| 135 print_json_ast = FLAG_print_builtin_json_ast; | 132 print_json_ast = FLAG_print_builtin_json_ast; |
| 136 ftype = "builtin"; | 133 ftype = "builtin"; |
| 137 } else { | 134 } else { |
| 138 print_source = FLAG_print_source; | 135 print_source = FLAG_print_source; |
| 139 print_ast = FLAG_print_ast; | 136 print_ast = FLAG_print_ast; |
| 140 print_json_ast = FLAG_print_json_ast; | 137 print_json_ast = FLAG_print_json_ast; |
| 141 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter); | 138 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter); |
| 142 if (print_source && !filter.is_empty()) { | 139 if (print_source && !filter.is_empty()) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 #endif // DEBUG | 171 #endif // DEBUG |
| 175 } | 172 } |
| 176 | 173 |
| 177 | 174 |
| 178 Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm, | 175 Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm, |
| 179 Code::Flags flags, | 176 Code::Flags flags, |
| 180 CompilationInfo* info) { | 177 CompilationInfo* info) { |
| 181 // Allocate and install the code. | 178 // Allocate and install the code. |
| 182 CodeDesc desc; | 179 CodeDesc desc; |
| 183 masm->GetCode(&desc); | 180 masm->GetCode(&desc); |
| 184 Handle<Code> code = Factory::NewCode(desc, flags, masm->CodeObject()); | 181 Handle<Code> code = FACTORY->NewCode(desc, flags, masm->CodeObject()); |
| 185 | 182 |
| 186 if (!code.is_null()) { | 183 if (!code.is_null()) { |
| 187 Counters::total_compiled_code_size.Increment(code->instruction_size()); | 184 COUNTERS->total_compiled_code_size()->Increment(code->instruction_size()); |
| 188 } | 185 } |
| 189 return code; | 186 return code; |
| 190 } | 187 } |
| 191 | 188 |
| 192 | 189 |
| 193 void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) { | 190 void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) { |
| 194 #ifdef ENABLE_DISASSEMBLER | 191 #ifdef ENABLE_DISASSEMBLER |
| 195 bool print_code = Bootstrapper::IsActive() | 192 bool print_code = Isolate::Current()->bootstrapper()->IsActive() |
| 196 ? FLAG_print_builtin_code | 193 ? FLAG_print_builtin_code |
| 197 : (FLAG_print_code || (info->IsOptimizing() && FLAG_print_opt_code)); | 194 : (FLAG_print_code || (info->IsOptimizing() && FLAG_print_opt_code)); |
| 198 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter); | 195 Vector<const char> filter = CStrVector(FLAG_hydrogen_filter); |
| 199 FunctionLiteral* function = info->function(); | 196 FunctionLiteral* function = info->function(); |
| 200 bool match = filter.is_empty() || function->debug_name()->IsEqualTo(filter); | 197 bool match = filter.is_empty() || function->debug_name()->IsEqualTo(filter); |
| 201 if (print_code && match) { | 198 if (print_code && match) { |
| 202 // Print the source code if available. | 199 // Print the source code if available. |
| 203 Handle<Script> script = info->script(); | 200 Handle<Script> script = info->script(); |
| 204 if (!script->IsUndefined() && !script->source()->IsUndefined()) { | 201 if (!script->IsUndefined() && !script->source()->IsUndefined()) { |
| 205 PrintF("--- Raw source ---\n"); | 202 PrintF("--- Raw source ---\n"); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 231 | 228 |
| 232 | 229 |
| 233 // Generate the code. Compile the AST and assemble all the pieces into a | 230 // Generate the code. Compile the AST and assemble all the pieces into a |
| 234 // Code object. | 231 // Code object. |
| 235 bool CodeGenerator::MakeCode(CompilationInfo* info) { | 232 bool CodeGenerator::MakeCode(CompilationInfo* info) { |
| 236 // When using Crankshaft the classic backend should never be used. | 233 // When using Crankshaft the classic backend should never be used. |
| 237 ASSERT(!V8::UseCrankshaft()); | 234 ASSERT(!V8::UseCrankshaft()); |
| 238 Handle<Script> script = info->script(); | 235 Handle<Script> script = info->script(); |
| 239 if (!script->IsUndefined() && !script->source()->IsUndefined()) { | 236 if (!script->IsUndefined() && !script->source()->IsUndefined()) { |
| 240 int len = String::cast(script->source())->length(); | 237 int len = String::cast(script->source())->length(); |
| 241 Counters::total_old_codegen_source_size.Increment(len); | 238 COUNTERS->total_old_codegen_source_size()->Increment(len); |
| 242 } | 239 } |
| 243 if (FLAG_trace_codegen) { | 240 if (FLAG_trace_codegen) { |
| 244 PrintF("Classic Compiler - "); | 241 PrintF("Classic Compiler - "); |
| 245 } | 242 } |
| 246 MakeCodePrologue(info); | 243 MakeCodePrologue(info); |
| 247 // Generate code. | 244 // Generate code. |
| 248 const int kInitialBufferSize = 4 * KB; | 245 const int kInitialBufferSize = 4 * KB; |
| 249 MacroAssembler masm(NULL, kInitialBufferSize); | 246 MacroAssembler masm(NULL, kInitialBufferSize); |
| 250 #ifdef ENABLE_GDB_JIT_INTERFACE | 247 #ifdef ENABLE_GDB_JIT_INTERFACE |
| 251 masm.positions_recorder()->StartGDBJITLineInfoRecording(); | 248 masm.positions_recorder()->StartGDBJITLineInfoRecording(); |
| 252 #endif | 249 #endif |
| 253 CodeGenerator cgen(&masm); | 250 CodeGenerator cgen(&masm); |
| 254 CodeGeneratorScope scope(&cgen); | 251 CodeGeneratorScope scope(Isolate::Current(), &cgen); |
| 255 cgen.Generate(info); | 252 cgen.Generate(info); |
| 256 if (cgen.HasStackOverflow()) { | 253 if (cgen.HasStackOverflow()) { |
| 257 ASSERT(!Top::has_pending_exception()); | 254 ASSERT(!Isolate::Current()->has_pending_exception()); |
| 258 return false; | 255 return false; |
| 259 } | 256 } |
| 260 | 257 |
| 261 InLoopFlag in_loop = info->is_in_loop() ? IN_LOOP : NOT_IN_LOOP; | 258 InLoopFlag in_loop = info->is_in_loop() ? IN_LOOP : NOT_IN_LOOP; |
| 262 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, in_loop); | 259 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, in_loop); |
| 263 Handle<Code> code = MakeCodeEpilogue(cgen.masm(), flags, info); | 260 Handle<Code> code = MakeCodeEpilogue(cgen.masm(), flags, info); |
| 264 // There is no stack check table in code generated by the classic backend. | 261 // There is no stack check table in code generated by the classic backend. |
| 265 code->SetNoStackCheckTable(); | 262 code->SetNoStackCheckTable(); |
| 266 CodeGenerator::PrintCode(code, info); | 263 CodeGenerator::PrintCode(code, info); |
| 267 info->SetCode(code); // May be an empty handle. | 264 info->SetCode(code); // May be an empty handle. |
| 268 #ifdef ENABLE_GDB_JIT_INTERFACE | 265 #ifdef ENABLE_GDB_JIT_INTERFACE |
| 269 if (FLAG_gdbjit && !code.is_null()) { | 266 if (FLAG_gdbjit && !code.is_null()) { |
| 270 GDBJITLineInfo* lineinfo = | 267 GDBJITLineInfo* lineinfo = |
| 271 masm.positions_recorder()->DetachGDBJITLineInfo(); | 268 masm.positions_recorder()->DetachGDBJITLineInfo(); |
| 272 | 269 |
| 273 GDBJIT(RegisterDetailedLineInfo(*code, lineinfo)); | 270 GDBJIT(RegisterDetailedLineInfo(*code, lineinfo)); |
| 274 } | 271 } |
| 275 #endif | 272 #endif |
| 276 return !code.is_null(); | 273 return !code.is_null(); |
| 277 } | 274 } |
| 278 | 275 |
| 279 | 276 |
| 280 #ifdef ENABLE_LOGGING_AND_PROFILING | 277 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 281 | 278 |
| 279 |
| 280 static Vector<const char> kRegexp = CStrVector("regexp"); |
| 281 |
| 282 |
| 282 bool CodeGenerator::ShouldGenerateLog(Expression* type) { | 283 bool CodeGenerator::ShouldGenerateLog(Expression* type) { |
| 283 ASSERT(type != NULL); | 284 ASSERT(type != NULL); |
| 284 if (!Logger::is_logging() && !CpuProfiler::is_profiling()) return false; | 285 if (!LOGGER->is_logging() && !CpuProfiler::is_profiling()) return false; |
| 285 Handle<String> name = Handle<String>::cast(type->AsLiteral()->handle()); | 286 Handle<String> name = Handle<String>::cast(type->AsLiteral()->handle()); |
| 286 if (FLAG_log_regexp) { | 287 if (FLAG_log_regexp) { |
| 287 static Vector<const char> kRegexp = CStrVector("regexp"); | |
| 288 if (name->IsEqualTo(kRegexp)) | 288 if (name->IsEqualTo(kRegexp)) |
| 289 return true; | 289 return true; |
| 290 } | 290 } |
| 291 return false; | 291 return false; |
| 292 } | 292 } |
| 293 | 293 |
| 294 #endif | 294 #endif |
| 295 | 295 |
| 296 | 296 |
| 297 void CodeGenerator::ProcessDeclarations(ZoneList<Declaration*>* declarations) { | 297 void CodeGenerator::ProcessDeclarations(ZoneList<Declaration*>* declarations) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 310 } else { | 310 } else { |
| 311 // Count global variables and functions for later processing | 311 // Count global variables and functions for later processing |
| 312 globals++; | 312 globals++; |
| 313 } | 313 } |
| 314 } | 314 } |
| 315 | 315 |
| 316 // Return in case of no declared global functions or variables. | 316 // Return in case of no declared global functions or variables. |
| 317 if (globals == 0) return; | 317 if (globals == 0) return; |
| 318 | 318 |
| 319 // Compute array of global variable and function declarations. | 319 // Compute array of global variable and function declarations. |
| 320 Handle<FixedArray> array = Factory::NewFixedArray(2 * globals, TENURED); | 320 Handle<FixedArray> array = FACTORY->NewFixedArray(2 * globals, TENURED); |
| 321 for (int j = 0, i = 0; i < length; i++) { | 321 for (int j = 0, i = 0; i < length; i++) { |
| 322 Declaration* node = declarations->at(i); | 322 Declaration* node = declarations->at(i); |
| 323 Variable* var = node->proxy()->var(); | 323 Variable* var = node->proxy()->var(); |
| 324 Slot* slot = var->AsSlot(); | 324 Slot* slot = var->AsSlot(); |
| 325 | 325 |
| 326 if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) { | 326 if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) { |
| 327 // Skip - already processed. | 327 // Skip - already processed. |
| 328 } else { | 328 } else { |
| 329 array->set(j++, *(var->name())); | 329 array->set(j++, *(var->name())); |
| 330 if (node->fun() == NULL) { | 330 if (node->fun() == NULL) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 CodeGenerator::kInlineFunctionGenerators[] = { | 367 CodeGenerator::kInlineFunctionGenerators[] = { |
| 368 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) | 368 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) |
| 369 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) | 369 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) |
| 370 }; | 370 }; |
| 371 #undef INLINE_FUNCTION_GENERATOR_ADDRESS | 371 #undef INLINE_FUNCTION_GENERATOR_ADDRESS |
| 372 | 372 |
| 373 | 373 |
| 374 bool CodeGenerator::CheckForInlineRuntimeCall(CallRuntime* node) { | 374 bool CodeGenerator::CheckForInlineRuntimeCall(CallRuntime* node) { |
| 375 ZoneList<Expression*>* args = node->arguments(); | 375 ZoneList<Expression*>* args = node->arguments(); |
| 376 Handle<String> name = node->name(); | 376 Handle<String> name = node->name(); |
| 377 Runtime::Function* function = node->function(); | 377 const Runtime::Function* function = node->function(); |
| 378 if (function != NULL && function->intrinsic_type == Runtime::INLINE) { | 378 if (function != NULL && function->intrinsic_type == Runtime::INLINE) { |
| 379 int lookup_index = static_cast<int>(function->function_id) - | 379 int lookup_index = static_cast<int>(function->function_id) - |
| 380 static_cast<int>(Runtime::kFirstInlineFunction); | 380 static_cast<int>(Runtime::kFirstInlineFunction); |
| 381 ASSERT(lookup_index >= 0); | 381 ASSERT(lookup_index >= 0); |
| 382 ASSERT(static_cast<size_t>(lookup_index) < | 382 ASSERT(static_cast<size_t>(lookup_index) < |
| 383 ARRAY_SIZE(kInlineFunctionGenerators)); | 383 ARRAY_SIZE(kInlineFunctionGenerators)); |
| 384 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; | 384 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; |
| 385 (this->*generator)(args); | 385 (this->*generator)(args); |
| 386 return true; | 386 return true; |
| 387 } | 387 } |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 int result = save_doubles_ ? 1 : 0; | 491 int result = save_doubles_ ? 1 : 0; |
| 492 #ifdef _WIN64 | 492 #ifdef _WIN64 |
| 493 return result | ((result_size_ == 1) ? 0 : 2); | 493 return result | ((result_size_ == 1) ? 0 : 2); |
| 494 #else | 494 #else |
| 495 return result; | 495 return result; |
| 496 #endif | 496 #endif |
| 497 } | 497 } |
| 498 | 498 |
| 499 | 499 |
| 500 } } // namespace v8::internal | 500 } } // namespace v8::internal |
| OLD | NEW |