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
UseCount()40 UseCount::UseCount()
41 : nreads_(0),
42 nwrites_(0) {
43 }
44
45
RecordRead(int weight)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
RecordWrite(int weight)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
RecordAccess(int weight)68 void UseCount::RecordAccess(int weight) {
69 RecordRead(weight);
70 RecordWrite(weight);
71 }
72
73
RecordUses(UseCount * uses)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
Print()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
Type2String(StaticType * type)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
Mode2String(Mode mode)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
AsProperty()124 Property* Variable::AsProperty() {
125 return rewrite_ == NULL ? NULL : rewrite_->AsProperty();
126 }
127
128
AsVariable()129 Variable* Variable::AsVariable() {
130 return rewrite_ == NULL || rewrite_->AsSlot() != NULL ? this : NULL;
131 }
132
133
slot() const134 Slot* Variable::slot() const {
135 return rewrite_ != NULL ? rewrite_->AsSlot() : NULL;
136 }
137
138
Variable(Scope * scope,Handle<String> name,Mode mode,bool is_valid_LHS,Kind kind)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
is_global() const157 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