1 // Copyright 2006-2008 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 "ast.h" 31 #include "scopes.h" 32 #include "variables.h" 33 34 namespace v8 { 35 namespace internal { 36 37 // ---------------------------------------------------------------------------- 38 // Implementation UseCount. 39 40 UseCount::UseCount() 41 : nreads_(0), 42 nwrites_(0) { 43 } 44 45 46 void UseCount::RecordRead(int weight) { 47 ASSERT(weight > 0); 48 nreads_ += weight; 49 // We must have a positive nreads_ here. Handle 50 // any kind of overflow by setting nreads_ to 51 // some large-ish value. 52 if (nreads_ <= 0) nreads_ = 1000000; 53 ASSERT(is_read() & is_used()); 54 } 55 56 57 void UseCount::RecordWrite(int weight) { 58 ASSERT(weight > 0); 59 nwrites_ += weight; 60 // We must have a positive nwrites_ here. Handle 61 // any kind of overflow by setting nwrites_ to 62 // some large-ish value. 63 if (nwrites_ <= 0) nwrites_ = 1000000; 64 ASSERT(is_written() && is_used()); 65 } 66 67 68 void UseCount::RecordAccess(int weight) { 69 RecordRead(weight); 70 RecordWrite(weight); 71 } 72 73 74 void UseCount::RecordUses(UseCount* uses) { 75 if (uses->nreads() > 0) RecordRead(uses->nreads()); 76 if (uses->nwrites() > 0) RecordWrite(uses->nwrites()); 77 } 78 79 80 #ifdef DEBUG 81 void UseCount::Print() { 82 // PrintF("r = %d, w = %d", nreads_, nwrites_); 83 PrintF("%du = %dr + %dw", nuses(), nreads(), nwrites()); 84 } 85 #endif 86 87 88 // ---------------------------------------------------------------------------- 89 // Implementation StaticType. 90 91 92 const char* StaticType::Type2String(StaticType* type) { 93 switch (type->kind_) { 94 case UNKNOWN: 95 return "UNKNOWN"; 96 case LIKELY_SMI: 97 return "LIKELY_SMI"; 98 default: 99 UNREACHABLE(); 100 } 101 return "UNREACHABLE"; 102 } 103 104 105 // ---------------------------------------------------------------------------- 106 // Implementation Variable. 107 108 109 const char* Variable::Mode2String(Mode mode) { 110 switch (mode) { 111 case VAR: return "VAR"; 112 case CONST: return "CONST"; 113 case DYNAMIC: return "DYNAMIC"; 114 case DYNAMIC_GLOBAL: return "DYNAMIC_GLOBAL"; 115 case DYNAMIC_LOCAL: return "DYNAMIC_LOCAL"; 116 case INTERNAL: return "INTERNAL"; 117 case TEMPORARY: return "TEMPORARY"; 118 } 119 UNREACHABLE(); 120 return NULL; 121 } 122 123 124 Property* Variable::AsProperty() { 125 return rewrite_ == NULL ? NULL : rewrite_->AsProperty(); 126 } 127 128 129 Variable* Variable::AsVariable() { 130 return rewrite_ == NULL || rewrite_->AsSlot() != NULL ? this : NULL; 131 } 132 133 134 Slot* Variable::slot() const { 135 return rewrite_ != NULL ? rewrite_->AsSlot() : NULL; 136 } 137 138 139 Variable::Variable(Scope* scope, 140 Handle<String> name, 141 Mode mode, 142 bool is_valid_LHS, 143 Kind kind) 144 : scope_(scope), 145 name_(name), 146 mode_(mode), 147 is_valid_LHS_(is_valid_LHS), 148 kind_(kind), 149 local_if_not_shadowed_(NULL), 150 is_accessed_from_inner_scope_(false), 151 rewrite_(NULL) { 152 // names must be canonicalized for fast equality checks 153 ASSERT(name->IsSymbol()); 154 } 155 156 157 bool Variable::is_global() const { 158 // Temporaries are never global, they must always be allocated in the 159 // activation frame. 160 return mode_ != TEMPORARY && scope_ != NULL && scope_->is_global_scope(); 161 } 162 163 } } // namespace v8::internal 164