Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     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.
     27 
     28 #include "v8.h"
     29 
     30 #include "bootstrapper.h"
     31 #include "codegen.h"
     32 #include "compiler.h"
     33 #include "debug.h"
     34 #include "prettyprinter.h"
     35 #include "rewriter.h"
     36 #include "runtime.h"
     37 #include "stub-cache.h"
     38 
     39 namespace v8 {
     40 namespace internal {
     41 
     42 #define __ ACCESS_MASM(masm_)
     43 
     44 #ifdef DEBUG
     45 
     46 Comment::Comment(MacroAssembler* masm, const char* msg)
     47     : masm_(masm), msg_(msg) {
     48   __ RecordComment(msg);
     49 }
     50 
     51 
     52 Comment::~Comment() {
     53   if (msg_[0] == '[') __ RecordComment("]");
     54 }
     55 
     56 #endif  // DEBUG
     57 
     58 #undef __
     59 
     60 
     61 void CodeGenerator::MakeCodePrologue(CompilationInfo* info) {
     62 #ifdef DEBUG
     63   bool print_source = false;
     64   bool print_ast = false;
     65   const char* ftype;
     66 
     67   if (Isolate::Current()->bootstrapper()->IsActive()) {
     68     print_source = FLAG_print_builtin_source;
     69     print_ast = FLAG_print_builtin_ast;
     70     ftype = "builtin";
     71   } else {
     72     print_source = FLAG_print_source;
     73     print_ast = FLAG_print_ast;
     74     ftype = "user-defined";
     75   }
     76 
     77   if (FLAG_trace_codegen || print_source || print_ast) {
     78     PrintF("*** Generate code for %s function: ", ftype);
     79     info->function()->name()->ShortPrint();
     80     PrintF(" ***\n");
     81   }
     82 
     83   if (print_source) {
     84     PrintF("--- Source from AST ---\n%s\n",
     85            PrettyPrinter().PrintProgram(info->function()));
     86   }
     87 
     88   if (print_ast) {
     89     PrintF("--- AST ---\n%s\n",
     90            AstPrinter().PrintProgram(info->function()));
     91   }
     92 #endif  // DEBUG
     93 }
     94 
     95 
     96 Handle<Code> CodeGenerator::MakeCodeEpilogue(MacroAssembler* masm,
     97                                              Code::Flags flags,
     98                                              CompilationInfo* info) {
     99   Isolate* isolate = info->isolate();
    100 
    101   // Allocate and install the code.
    102   CodeDesc desc;
    103   masm->GetCode(&desc);
    104   Handle<Code> code =
    105       isolate->factory()->NewCode(desc, flags, masm->CodeObject());
    106 
    107   if (!code.is_null()) {
    108     isolate->counters()->total_compiled_code_size()->Increment(
    109         code->instruction_size());
    110   }
    111   return code;
    112 }
    113 
    114 
    115 void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) {
    116 #ifdef ENABLE_DISASSEMBLER
    117   bool print_code = Isolate::Current()->bootstrapper()->IsActive()
    118       ? FLAG_print_builtin_code
    119       : (FLAG_print_code || (info->IsOptimizing() && FLAG_print_opt_code));
    120   if (print_code) {
    121     // Print the source code if available.
    122     FunctionLiteral* function = info->function();
    123     Handle<Script> script = info->script();
    124     if (!script->IsUndefined() && !script->source()->IsUndefined()) {
    125       PrintF("--- Raw source ---\n");
    126       StringInputBuffer stream(String::cast(script->source()));
    127       stream.Seek(function->start_position());
    128       // fun->end_position() points to the last character in the stream. We
    129       // need to compensate by adding one to calculate the length.
    130       int source_len =
    131           function->end_position() - function->start_position() + 1;
    132       for (int i = 0; i < source_len; i++) {
    133         if (stream.has_more()) PrintF("%c", stream.GetNext());
    134       }
    135       PrintF("\n\n");
    136     }
    137     if (info->IsOptimizing()) {
    138       if (FLAG_print_unopt_code) {
    139         PrintF("--- Unoptimized code ---\n");
    140         info->closure()->shared()->code()->Disassemble(
    141             *function->debug_name()->ToCString());
    142       }
    143       PrintF("--- Optimized code ---\n");
    144     } else {
    145       PrintF("--- Code ---\n");
    146     }
    147     code->Disassemble(*function->debug_name()->ToCString());
    148   }
    149 #endif  // ENABLE_DISASSEMBLER
    150 }
    151 
    152 
    153 bool CodeGenerator::ShouldGenerateLog(Expression* type) {
    154   ASSERT(type != NULL);
    155   Isolate* isolate = Isolate::Current();
    156   if (!isolate->logger()->is_logging() && !CpuProfiler::is_profiling(isolate)) {
    157     return false;
    158   }
    159   Handle<String> name = Handle<String>::cast(type->AsLiteral()->handle());
    160   if (FLAG_log_regexp) {
    161     if (name->IsEqualTo(CStrVector("regexp")))
    162       return true;
    163   }
    164   return false;
    165 }
    166 
    167 
    168 bool CodeGenerator::RecordPositions(MacroAssembler* masm,
    169                                     int pos,
    170                                     bool right_here) {
    171   if (pos != RelocInfo::kNoPosition) {
    172     masm->positions_recorder()->RecordStatementPosition(pos);
    173     masm->positions_recorder()->RecordPosition(pos);
    174     if (right_here) {
    175       return masm->positions_recorder()->WriteRecordedPositions();
    176     }
    177   }
    178   return false;
    179 }
    180 
    181 
    182 void ArgumentsAccessStub::Generate(MacroAssembler* masm) {
    183   switch (type_) {
    184     case READ_ELEMENT:
    185       GenerateReadElement(masm);
    186       break;
    187     case NEW_NON_STRICT_FAST:
    188       GenerateNewNonStrictFast(masm);
    189       break;
    190     case NEW_NON_STRICT_SLOW:
    191       GenerateNewNonStrictSlow(masm);
    192       break;
    193     case NEW_STRICT:
    194       GenerateNewStrict(masm);
    195       break;
    196   }
    197 }
    198 
    199 
    200 int CEntryStub::MinorKey() {
    201   int result = (save_doubles_ == kSaveFPRegs) ? 1 : 0;
    202   ASSERT(result_size_ == 1 || result_size_ == 2);
    203 #ifdef _WIN64
    204   return result | ((result_size_ == 1) ? 0 : 2);
    205 #else
    206   return result;
    207 #endif
    208 }
    209 
    210 
    211 } }  // namespace v8::internal
    212