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

Side by Side Diff: src/codegen.cc

Issue 6811012: Remove some dead code. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 8 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/codegen.h ('k') | src/codegen-inl.h » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2011 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
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
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 "bootstrapper.h" 30 #include "bootstrapper.h"
31 #include "codegen-inl.h" 31 #include "codegen.h"
32 #include "compiler.h" 32 #include "compiler.h"
33 #include "debug.h" 33 #include "debug.h"
34 #include "prettyprinter.h" 34 #include "prettyprinter.h"
35 #include "register-allocator-inl.h"
36 #include "rewriter.h" 35 #include "rewriter.h"
37 #include "runtime.h" 36 #include "runtime.h"
38 #include "scopeinfo.h" 37 #include "scopeinfo.h"
39 #include "stub-cache.h" 38 #include "stub-cache.h"
40 #include "virtual-frame-inl.h"
41 39
42 namespace v8 { 40 namespace v8 {
43 namespace internal { 41 namespace internal {
44 42
45 #define __ ACCESS_MASM(masm_) 43 #define __ ACCESS_MASM(masm_)
46 44
47 #ifdef DEBUG 45 #ifdef DEBUG
48 46
49 Comment::Comment(MacroAssembler* masm, const char* msg) 47 Comment::Comment(MacroAssembler* masm, const char* msg)
50 : masm_(masm), msg_(msg) { 48 : masm_(masm), msg_(msg) {
51 __ RecordComment(msg); 49 __ RecordComment(msg);
52 } 50 }
53 51
54 52
55 Comment::~Comment() { 53 Comment::~Comment() {
56 if (msg_[0] == '[') __ RecordComment("]"); 54 if (msg_[0] == '[') __ RecordComment("]");
57 } 55 }
58 56
59 #endif // DEBUG 57 #endif // DEBUG
60 58
61 #undef __ 59 #undef __
62 60
63 61
64 void CodeGenerator::ProcessDeferred() {
65 while (!deferred_.is_empty()) {
66 DeferredCode* code = deferred_.RemoveLast();
67 ASSERT(masm_ == code->masm());
68 // Record position of deferred code stub.
69 masm_->positions_recorder()->RecordStatementPosition(
70 code->statement_position());
71 if (code->position() != RelocInfo::kNoPosition) {
72 masm_->positions_recorder()->RecordPosition(code->position());
73 }
74 // Generate the code.
75 Comment cmnt(masm_, code->comment());
76 masm_->bind(code->entry_label());
77 if (code->AutoSaveAndRestore()) {
78 code->SaveRegisters();
79 }
80 code->Generate();
81 if (code->AutoSaveAndRestore()) {
82 code->RestoreRegisters();
83 code->Exit();
84 }
85 }
86 }
87
88
89 void DeferredCode::Exit() {
90 masm_->jmp(exit_label());
91 }
92
93
94 void CodeGenerator::SetFrame(VirtualFrame* new_frame,
95 RegisterFile* non_frame_registers) {
96 RegisterFile saved_counts;
97 if (has_valid_frame()) {
98 frame_->DetachFromCodeGenerator();
99 // The remaining register reference counts are the non-frame ones.
100 allocator_->SaveTo(&saved_counts);
101 }
102
103 if (new_frame != NULL) {
104 // Restore the non-frame register references that go with the new frame.
105 allocator_->RestoreFrom(non_frame_registers);
106 new_frame->AttachToCodeGenerator();
107 }
108
109 frame_ = new_frame;
110 saved_counts.CopyTo(non_frame_registers);
111 }
112
113
114 void CodeGenerator::DeleteFrame() {
115 if (has_valid_frame()) {
116 frame_->DetachFromCodeGenerator();
117 frame_ = NULL;
118 }
119 }
120
121
122 void CodeGenerator::MakeCodePrologue(CompilationInfo* info) { 62 void CodeGenerator::MakeCodePrologue(CompilationInfo* info) {
123 #ifdef DEBUG 63 #ifdef DEBUG
124 bool print_source = false; 64 bool print_source = false;
125 bool print_ast = false; 65 bool print_ast = false;
126 bool print_json_ast = false; 66 bool print_json_ast = false;
127 const char* ftype; 67 const char* ftype;
128 68
129 if (Isolate::Current()->bootstrapper()->IsActive()) { 69 if (Isolate::Current()->bootstrapper()->IsActive()) {
130 print_source = FLAG_print_builtin_source; 70 print_source = FLAG_print_builtin_source;
131 print_ast = FLAG_print_builtin_ast; 71 print_ast = FLAG_print_builtin_ast;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 } 163 }
224 PrintF("--- Optimized code ---\n"); 164 PrintF("--- Optimized code ---\n");
225 } else { 165 } else {
226 PrintF("--- Code ---\n"); 166 PrintF("--- Code ---\n");
227 } 167 }
228 code->Disassemble(*function->debug_name()->ToCString()); 168 code->Disassemble(*function->debug_name()->ToCString());
229 } 169 }
230 #endif // ENABLE_DISASSEMBLER 170 #endif // ENABLE_DISASSEMBLER
231 } 171 }
232 172
233
234 // Generate the code. Compile the AST and assemble all the pieces into a
235 // Code object.
236 bool CodeGenerator::MakeCode(CompilationInfo* info) {
237 // When using Crankshaft the classic backend should never be used.
238 ASSERT(!V8::UseCrankshaft());
239 Handle<Script> script = info->script();
240 if (!script->IsUndefined() && !script->source()->IsUndefined()) {
241 int len = String::cast(script->source())->length();
242 Counters* counters = info->isolate()->counters();
243 counters->total_old_codegen_source_size()->Increment(len);
244 }
245 if (FLAG_trace_codegen) {
246 PrintF("Classic Compiler - ");
247 }
248 MakeCodePrologue(info);
249 // Generate code.
250 const int kInitialBufferSize = 4 * KB;
251 MacroAssembler masm(info->isolate(), NULL, kInitialBufferSize);
252 #ifdef ENABLE_GDB_JIT_INTERFACE
253 masm.positions_recorder()->StartGDBJITLineInfoRecording();
254 #endif
255 CodeGenerator cgen(&masm);
256 CodeGeneratorScope scope(Isolate::Current(), &cgen);
257 cgen.Generate(info);
258 if (cgen.HasStackOverflow()) {
259 ASSERT(!Isolate::Current()->has_pending_exception());
260 return false;
261 }
262
263 InLoopFlag in_loop = info->is_in_loop() ? IN_LOOP : NOT_IN_LOOP;
264 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, in_loop);
265 Handle<Code> code = MakeCodeEpilogue(cgen.masm(), flags, info);
266 // There is no stack check table in code generated by the classic backend.
267 code->SetNoStackCheckTable();
268 CodeGenerator::PrintCode(code, info);
269 info->SetCode(code); // May be an empty handle.
270 #ifdef ENABLE_GDB_JIT_INTERFACE
271 if (FLAG_gdbjit && !code.is_null()) {
272 GDBJITLineInfo* lineinfo =
273 masm.positions_recorder()->DetachGDBJITLineInfo();
274
275 GDBJIT(RegisterDetailedLineInfo(*code, lineinfo));
276 }
277 #endif
278 return !code.is_null();
279 }
280
281
282 #ifdef ENABLE_LOGGING_AND_PROFILING 173 #ifdef ENABLE_LOGGING_AND_PROFILING
283 174
284
285 static Vector<const char> kRegexp = CStrVector("regexp"); 175 static Vector<const char> kRegexp = CStrVector("regexp");
286 176
287
288 bool CodeGenerator::ShouldGenerateLog(Expression* type) { 177 bool CodeGenerator::ShouldGenerateLog(Expression* type) {
289 ASSERT(type != NULL); 178 ASSERT(type != NULL);
290 if (!LOGGER->is_logging() && !CpuProfiler::is_profiling()) return false; 179 if (!LOGGER->is_logging() && !CpuProfiler::is_profiling()) return false;
291 Handle<String> name = Handle<String>::cast(type->AsLiteral()->handle()); 180 Handle<String> name = Handle<String>::cast(type->AsLiteral()->handle());
292 if (FLAG_log_regexp) { 181 if (FLAG_log_regexp) {
293 if (name->IsEqualTo(kRegexp)) 182 if (name->IsEqualTo(kRegexp))
294 return true; 183 return true;
295 } 184 }
296 return false; 185 return false;
297 } 186 }
298 187
299 #endif 188 #endif
300 189
301 190
302 void CodeGenerator::ProcessDeclarations(ZoneList<Declaration*>* declarations) {
303 int length = declarations->length();
304 int globals = 0;
305 for (int i = 0; i < length; i++) {
306 Declaration* node = declarations->at(i);
307 Variable* var = node->proxy()->var();
308 Slot* slot = var->AsSlot();
309
310 // If it was not possible to allocate the variable at compile
311 // time, we need to "declare" it at runtime to make sure it
312 // actually exists in the local context.
313 if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) {
314 VisitDeclaration(node);
315 } else {
316 // Count global variables and functions for later processing
317 globals++;
318 }
319 }
320
321 // Return in case of no declared global functions or variables.
322 if (globals == 0) return;
323
324 // Compute array of global variable and function declarations.
325 Handle<FixedArray> array = FACTORY->NewFixedArray(2 * globals, TENURED);
326 for (int j = 0, i = 0; i < length; i++) {
327 Declaration* node = declarations->at(i);
328 Variable* var = node->proxy()->var();
329 Slot* slot = var->AsSlot();
330
331 if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) {
332 // Skip - already processed.
333 } else {
334 array->set(j++, *(var->name()));
335 if (node->fun() == NULL) {
336 if (var->mode() == Variable::CONST) {
337 // In case this is const property use the hole.
338 array->set_the_hole(j++);
339 } else {
340 array->set_undefined(j++);
341 }
342 } else {
343 Handle<SharedFunctionInfo> function =
344 Compiler::BuildFunctionInfo(node->fun(), script());
345 // Check for stack-overflow exception.
346 if (function.is_null()) {
347 SetStackOverflow();
348 return;
349 }
350 array->set(j++, *function);
351 }
352 }
353 }
354
355 // Invoke the platform-dependent code generator to do the actual
356 // declaration the global variables and functions.
357 DeclareGlobals(array);
358 }
359
360
361 void CodeGenerator::VisitIncrementOperation(IncrementOperation* expr) {
362 UNREACHABLE();
363 }
364
365
366 // Lookup table for code generators for special runtime calls which are
367 // generated inline.
368 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \
369 &CodeGenerator::Generate##Name,
370
371 const CodeGenerator::InlineFunctionGenerator
372 CodeGenerator::kInlineFunctionGenerators[] = {
373 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
374 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
375 };
376 #undef INLINE_FUNCTION_GENERATOR_ADDRESS
377
378
379 bool CodeGenerator::CheckForInlineRuntimeCall(CallRuntime* node) {
380 ZoneList<Expression*>* args = node->arguments();
381 Handle<String> name = node->name();
382 const Runtime::Function* function = node->function();
383 if (function != NULL && function->intrinsic_type == Runtime::INLINE) {
384 int lookup_index = static_cast<int>(function->function_id) -
385 static_cast<int>(Runtime::kFirstInlineFunction);
386 ASSERT(lookup_index >= 0);
387 ASSERT(static_cast<size_t>(lookup_index) <
388 ARRAY_SIZE(kInlineFunctionGenerators));
389 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index];
390 (this->*generator)(args);
391 return true;
392 }
393 return false;
394 }
395
396
397 // Simple condition analysis. ALWAYS_TRUE and ALWAYS_FALSE represent a
398 // known result for the test expression, with no side effects.
399 CodeGenerator::ConditionAnalysis CodeGenerator::AnalyzeCondition(
400 Expression* cond) {
401 if (cond == NULL) return ALWAYS_TRUE;
402
403 Literal* lit = cond->AsLiteral();
404 if (lit == NULL) return DONT_KNOW;
405
406 if (lit->IsTrue()) {
407 return ALWAYS_TRUE;
408 } else if (lit->IsFalse()) {
409 return ALWAYS_FALSE;
410 }
411
412 return DONT_KNOW;
413 }
414
415
416 bool CodeGenerator::RecordPositions(MacroAssembler* masm, 191 bool CodeGenerator::RecordPositions(MacroAssembler* masm,
417 int pos, 192 int pos,
418 bool right_here) { 193 bool right_here) {
419 if (pos != RelocInfo::kNoPosition) { 194 if (pos != RelocInfo::kNoPosition) {
420 masm->positions_recorder()->RecordStatementPosition(pos); 195 masm->positions_recorder()->RecordStatementPosition(pos);
421 masm->positions_recorder()->RecordPosition(pos); 196 masm->positions_recorder()->RecordPosition(pos);
422 if (right_here) { 197 if (right_here) {
423 return masm->positions_recorder()->WriteRecordedPositions(); 198 return masm->positions_recorder()->WriteRecordedPositions();
424 } 199 }
425 } 200 }
426 return false; 201 return false;
427 } 202 }
428 203
429 204
430 void CodeGenerator::CodeForFunctionPosition(FunctionLiteral* fun) {
431 if (FLAG_debug_info) RecordPositions(masm(), fun->start_position(), false);
432 }
433
434
435 void CodeGenerator::CodeForReturnPosition(FunctionLiteral* fun) {
436 if (FLAG_debug_info) RecordPositions(masm(), fun->end_position() - 1, false);
437 }
438
439
440 void CodeGenerator::CodeForStatementPosition(Statement* stmt) {
441 if (FLAG_debug_info) RecordPositions(masm(), stmt->statement_pos(), false);
442 }
443
444
445 void CodeGenerator::CodeForDoWhileConditionPosition(DoWhileStatement* stmt) {
446 if (FLAG_debug_info)
447 RecordPositions(masm(), stmt->condition_position(), false);
448 }
449
450
451 void CodeGenerator::CodeForSourcePosition(int pos) {
452 if (FLAG_debug_info && pos != RelocInfo::kNoPosition) {
453 masm()->positions_recorder()->RecordPosition(pos);
454 }
455 }
456
457
458 const char* GenericUnaryOpStub::GetName() { 205 const char* GenericUnaryOpStub::GetName() {
459 switch (op_) { 206 switch (op_) {
460 case Token::SUB: 207 case Token::SUB:
461 if (negative_zero_ == kStrictNegativeZero) { 208 if (negative_zero_ == kStrictNegativeZero) {
462 return overwrite_ == UNARY_OVERWRITE 209 return overwrite_ == UNARY_OVERWRITE
463 ? "GenericUnaryOpStub_SUB_Overwrite_Strict0" 210 ? "GenericUnaryOpStub_SUB_Overwrite_Strict0"
464 : "GenericUnaryOpStub_SUB_Alloc_Strict0"; 211 : "GenericUnaryOpStub_SUB_Alloc_Strict0";
465 } else { 212 } else {
466 return overwrite_ == UNARY_OVERWRITE 213 return overwrite_ == UNARY_OVERWRITE
467 ? "GenericUnaryOpStub_SUB_Overwrite_Ignore0" 214 ? "GenericUnaryOpStub_SUB_Overwrite_Ignore0"
(...skipping 28 matching lines...) Expand all
496 int result = save_doubles_ ? 1 : 0; 243 int result = save_doubles_ ? 1 : 0;
497 #ifdef _WIN64 244 #ifdef _WIN64
498 return result | ((result_size_ == 1) ? 0 : 2); 245 return result | ((result_size_ == 1) ? 0 : 2);
499 #else 246 #else
500 return result; 247 return result;
501 #endif 248 #endif
502 } 249 }
503 250
504 251
505 } } // namespace v8::internal 252 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen.h ('k') | src/codegen-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698