OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/debug.h" | 8 #include "src/debug.h" |
9 #include "src/scopeinfo.h" | 9 #include "src/scopeinfo.h" |
10 | 10 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 | 13 |
14 Context* Context::declaration_context() { | 14 Context* Context::declaration_context() { |
15 Context* current = this; | 15 Context* current = this; |
16 while (!current->IsFunctionContext() && !current->IsNativeContext()) { | 16 while (!current->IsFunctionContext() && !current->IsNativeContext()) { |
17 current = current->previous(); | 17 current = current->previous(); |
18 ASSERT(current->closure() == closure()); | 18 DCHECK(current->closure() == closure()); |
19 } | 19 } |
20 return current; | 20 return current; |
21 } | 21 } |
22 | 22 |
23 | 23 |
24 JSBuiltinsObject* Context::builtins() { | 24 JSBuiltinsObject* Context::builtins() { |
25 GlobalObject* object = global_object(); | 25 GlobalObject* object = global_object(); |
26 if (object->IsJSGlobalObject()) { | 26 if (object->IsJSGlobalObject()) { |
27 return JSGlobalObject::cast(object)->builtins(); | 27 return JSGlobalObject::cast(object)->builtins(); |
28 } else { | 28 } else { |
29 ASSERT(object->IsJSBuiltinsObject()); | 29 DCHECK(object->IsJSBuiltinsObject()); |
30 return JSBuiltinsObject::cast(object); | 30 return JSBuiltinsObject::cast(object); |
31 } | 31 } |
32 } | 32 } |
33 | 33 |
34 | 34 |
35 Context* Context::global_context() { | 35 Context* Context::global_context() { |
36 Context* current = this; | 36 Context* current = this; |
37 while (!current->IsGlobalContext()) { | 37 while (!current->IsGlobalContext()) { |
38 current = current->previous(); | 38 current = current->previous(); |
39 } | 39 } |
40 return current; | 40 return current; |
41 } | 41 } |
42 | 42 |
43 | 43 |
44 Context* Context::native_context() { | 44 Context* Context::native_context() { |
45 // Fast case: the global object for this context has been set. In | 45 // Fast case: the global object for this context has been set. In |
46 // that case, the global object has a direct pointer to the global | 46 // that case, the global object has a direct pointer to the global |
47 // context. | 47 // context. |
48 if (global_object()->IsGlobalObject()) { | 48 if (global_object()->IsGlobalObject()) { |
49 return global_object()->native_context(); | 49 return global_object()->native_context(); |
50 } | 50 } |
51 | 51 |
52 // During bootstrapping, the global object might not be set and we | 52 // During bootstrapping, the global object might not be set and we |
53 // have to search the context chain to find the native context. | 53 // have to search the context chain to find the native context. |
54 ASSERT(this->GetIsolate()->bootstrapper()->IsActive()); | 54 DCHECK(this->GetIsolate()->bootstrapper()->IsActive()); |
55 Context* current = this; | 55 Context* current = this; |
56 while (!current->IsNativeContext()) { | 56 while (!current->IsNativeContext()) { |
57 JSFunction* closure = JSFunction::cast(current->closure()); | 57 JSFunction* closure = JSFunction::cast(current->closure()); |
58 current = Context::cast(closure->context()); | 58 current = Context::cast(closure->context()); |
59 } | 59 } |
60 return current; | 60 return current; |
61 } | 61 } |
62 | 62 |
63 | 63 |
64 JSObject* Context::global_proxy() { | 64 JSObject* Context::global_proxy() { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 // prototype. So even if we want to follow prototype chains, we need | 107 // prototype. So even if we want to follow prototype chains, we need |
108 // to only do a local lookup for context extension objects. | 108 // to only do a local lookup for context extension objects. |
109 Maybe<PropertyAttributes> maybe; | 109 Maybe<PropertyAttributes> maybe; |
110 if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 || | 110 if ((flags & FOLLOW_PROTOTYPE_CHAIN) == 0 || |
111 object->IsJSContextExtensionObject()) { | 111 object->IsJSContextExtensionObject()) { |
112 maybe = JSReceiver::GetOwnPropertyAttributes(object, name); | 112 maybe = JSReceiver::GetOwnPropertyAttributes(object, name); |
113 } else { | 113 } else { |
114 maybe = JSReceiver::GetPropertyAttributes(object, name); | 114 maybe = JSReceiver::GetPropertyAttributes(object, name); |
115 } | 115 } |
116 if (!maybe.has_value) return Handle<Object>(); | 116 if (!maybe.has_value) return Handle<Object>(); |
117 ASSERT(!isolate->has_pending_exception()); | 117 DCHECK(!isolate->has_pending_exception()); |
118 *attributes = maybe.value; | 118 *attributes = maybe.value; |
119 | 119 |
120 if (maybe.value != ABSENT) { | 120 if (maybe.value != ABSENT) { |
121 if (FLAG_trace_contexts) { | 121 if (FLAG_trace_contexts) { |
122 PrintF("=> found property in context object %p\n", | 122 PrintF("=> found property in context object %p\n", |
123 reinterpret_cast<void*>(*object)); | 123 reinterpret_cast<void*>(*object)); |
124 } | 124 } |
125 return object; | 125 return object; |
126 } | 126 } |
127 } | 127 } |
(...skipping 10 matching lines...) Expand all Loading... |
138 scope_info = Handle<ScopeInfo>( | 138 scope_info = Handle<ScopeInfo>( |
139 ScopeInfo::cast(context->extension()), isolate); | 139 ScopeInfo::cast(context->extension()), isolate); |
140 } | 140 } |
141 VariableMode mode; | 141 VariableMode mode; |
142 InitializationFlag init_flag; | 142 InitializationFlag init_flag; |
143 // TODO(sigurds) Figure out whether maybe_assigned_flag should | 143 // TODO(sigurds) Figure out whether maybe_assigned_flag should |
144 // be used to compute binding_flags. | 144 // be used to compute binding_flags. |
145 MaybeAssignedFlag maybe_assigned_flag; | 145 MaybeAssignedFlag maybe_assigned_flag; |
146 int slot_index = ScopeInfo::ContextSlotIndex( | 146 int slot_index = ScopeInfo::ContextSlotIndex( |
147 scope_info, name, &mode, &init_flag, &maybe_assigned_flag); | 147 scope_info, name, &mode, &init_flag, &maybe_assigned_flag); |
148 ASSERT(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS); | 148 DCHECK(slot_index < 0 || slot_index >= MIN_CONTEXT_SLOTS); |
149 if (slot_index >= 0) { | 149 if (slot_index >= 0) { |
150 if (FLAG_trace_contexts) { | 150 if (FLAG_trace_contexts) { |
151 PrintF("=> found local in context slot %d (mode = %d)\n", | 151 PrintF("=> found local in context slot %d (mode = %d)\n", |
152 slot_index, mode); | 152 slot_index, mode); |
153 } | 153 } |
154 *index = slot_index; | 154 *index = slot_index; |
155 // Note: Fixed context slots are statically allocated by the compiler. | 155 // Note: Fixed context slots are statically allocated by the compiler. |
156 // Statically allocated variables always have a statically known mode, | 156 // Statically allocated variables always have a statically known mode, |
157 // which is the mode with which they were declared when added to the | 157 // which is the mode with which they were declared when added to the |
158 // scope. Thus, the DYNAMIC mode (which corresponds to dynamically | 158 // scope. Thus, the DYNAMIC mode (which corresponds to dynamically |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 if (follow_context_chain && context->IsFunctionContext()) { | 199 if (follow_context_chain && context->IsFunctionContext()) { |
200 VariableMode mode; | 200 VariableMode mode; |
201 int function_index = scope_info->FunctionContextSlotIndex(*name, &mode); | 201 int function_index = scope_info->FunctionContextSlotIndex(*name, &mode); |
202 if (function_index >= 0) { | 202 if (function_index >= 0) { |
203 if (FLAG_trace_contexts) { | 203 if (FLAG_trace_contexts) { |
204 PrintF("=> found intermediate function in context slot %d\n", | 204 PrintF("=> found intermediate function in context slot %d\n", |
205 function_index); | 205 function_index); |
206 } | 206 } |
207 *index = function_index; | 207 *index = function_index; |
208 *attributes = READ_ONLY; | 208 *attributes = READ_ONLY; |
209 ASSERT(mode == CONST_LEGACY || mode == CONST); | 209 DCHECK(mode == CONST_LEGACY || mode == CONST); |
210 *binding_flags = (mode == CONST_LEGACY) | 210 *binding_flags = (mode == CONST_LEGACY) |
211 ? IMMUTABLE_IS_INITIALIZED : IMMUTABLE_IS_INITIALIZED_HARMONY; | 211 ? IMMUTABLE_IS_INITIALIZED : IMMUTABLE_IS_INITIALIZED_HARMONY; |
212 return context; | 212 return context; |
213 } | 213 } |
214 } | 214 } |
215 | 215 |
216 } else if (context->IsCatchContext()) { | 216 } else if (context->IsCatchContext()) { |
217 // Catch contexts have the variable name in the extension slot. | 217 // Catch contexts have the variable name in the extension slot. |
218 if (String::Equals(name, handle(String::cast(context->extension())))) { | 218 if (String::Equals(name, handle(String::cast(context->extension())))) { |
219 if (FLAG_trace_contexts) { | 219 if (FLAG_trace_contexts) { |
(...skipping 15 matching lines...) Expand all Loading... |
235 } while (follow_context_chain); | 235 } while (follow_context_chain); |
236 | 236 |
237 if (FLAG_trace_contexts) { | 237 if (FLAG_trace_contexts) { |
238 PrintF("=> no property/slot found\n"); | 238 PrintF("=> no property/slot found\n"); |
239 } | 239 } |
240 return Handle<Object>::null(); | 240 return Handle<Object>::null(); |
241 } | 241 } |
242 | 242 |
243 | 243 |
244 void Context::AddOptimizedFunction(JSFunction* function) { | 244 void Context::AddOptimizedFunction(JSFunction* function) { |
245 ASSERT(IsNativeContext()); | 245 DCHECK(IsNativeContext()); |
246 #ifdef ENABLE_SLOW_ASSERTS | 246 #ifdef ENABLE_SLOW_DCHECKS |
247 if (FLAG_enable_slow_asserts) { | 247 if (FLAG_enable_slow_asserts) { |
248 Object* element = get(OPTIMIZED_FUNCTIONS_LIST); | 248 Object* element = get(OPTIMIZED_FUNCTIONS_LIST); |
249 while (!element->IsUndefined()) { | 249 while (!element->IsUndefined()) { |
250 CHECK(element != function); | 250 CHECK(element != function); |
251 element = JSFunction::cast(element)->next_function_link(); | 251 element = JSFunction::cast(element)->next_function_link(); |
252 } | 252 } |
253 } | 253 } |
254 | 254 |
255 // Check that the context belongs to the weak native contexts list. | 255 // Check that the context belongs to the weak native contexts list. |
256 bool found = false; | 256 bool found = false; |
257 Object* context = GetHeap()->native_contexts_list(); | 257 Object* context = GetHeap()->native_contexts_list(); |
258 while (!context->IsUndefined()) { | 258 while (!context->IsUndefined()) { |
259 if (context == this) { | 259 if (context == this) { |
260 found = true; | 260 found = true; |
261 break; | 261 break; |
262 } | 262 } |
263 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); | 263 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); |
264 } | 264 } |
265 CHECK(found); | 265 CHECK(found); |
266 #endif | 266 #endif |
267 | 267 |
268 // If the function link field is already used then the function was | 268 // If the function link field is already used then the function was |
269 // enqueued as a code flushing candidate and we remove it now. | 269 // enqueued as a code flushing candidate and we remove it now. |
270 if (!function->next_function_link()->IsUndefined()) { | 270 if (!function->next_function_link()->IsUndefined()) { |
271 CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher(); | 271 CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher(); |
272 flusher->EvictCandidate(function); | 272 flusher->EvictCandidate(function); |
273 } | 273 } |
274 | 274 |
275 ASSERT(function->next_function_link()->IsUndefined()); | 275 DCHECK(function->next_function_link()->IsUndefined()); |
276 | 276 |
277 function->set_next_function_link(get(OPTIMIZED_FUNCTIONS_LIST)); | 277 function->set_next_function_link(get(OPTIMIZED_FUNCTIONS_LIST)); |
278 set(OPTIMIZED_FUNCTIONS_LIST, function); | 278 set(OPTIMIZED_FUNCTIONS_LIST, function); |
279 } | 279 } |
280 | 280 |
281 | 281 |
282 void Context::RemoveOptimizedFunction(JSFunction* function) { | 282 void Context::RemoveOptimizedFunction(JSFunction* function) { |
283 ASSERT(IsNativeContext()); | 283 DCHECK(IsNativeContext()); |
284 Object* element = get(OPTIMIZED_FUNCTIONS_LIST); | 284 Object* element = get(OPTIMIZED_FUNCTIONS_LIST); |
285 JSFunction* prev = NULL; | 285 JSFunction* prev = NULL; |
286 while (!element->IsUndefined()) { | 286 while (!element->IsUndefined()) { |
287 JSFunction* element_function = JSFunction::cast(element); | 287 JSFunction* element_function = JSFunction::cast(element); |
288 ASSERT(element_function->next_function_link()->IsUndefined() || | 288 DCHECK(element_function->next_function_link()->IsUndefined() || |
289 element_function->next_function_link()->IsJSFunction()); | 289 element_function->next_function_link()->IsJSFunction()); |
290 if (element_function == function) { | 290 if (element_function == function) { |
291 if (prev == NULL) { | 291 if (prev == NULL) { |
292 set(OPTIMIZED_FUNCTIONS_LIST, element_function->next_function_link()); | 292 set(OPTIMIZED_FUNCTIONS_LIST, element_function->next_function_link()); |
293 } else { | 293 } else { |
294 prev->set_next_function_link(element_function->next_function_link()); | 294 prev->set_next_function_link(element_function->next_function_link()); |
295 } | 295 } |
296 element_function->set_next_function_link(GetHeap()->undefined_value()); | 296 element_function->set_next_function_link(GetHeap()->undefined_value()); |
297 return; | 297 return; |
298 } | 298 } |
299 prev = element_function; | 299 prev = element_function; |
300 element = element_function->next_function_link(); | 300 element = element_function->next_function_link(); |
301 } | 301 } |
302 UNREACHABLE(); | 302 UNREACHABLE(); |
303 } | 303 } |
304 | 304 |
305 | 305 |
306 void Context::SetOptimizedFunctionsListHead(Object* head) { | 306 void Context::SetOptimizedFunctionsListHead(Object* head) { |
307 ASSERT(IsNativeContext()); | 307 DCHECK(IsNativeContext()); |
308 set(OPTIMIZED_FUNCTIONS_LIST, head); | 308 set(OPTIMIZED_FUNCTIONS_LIST, head); |
309 } | 309 } |
310 | 310 |
311 | 311 |
312 Object* Context::OptimizedFunctionsListHead() { | 312 Object* Context::OptimizedFunctionsListHead() { |
313 ASSERT(IsNativeContext()); | 313 DCHECK(IsNativeContext()); |
314 return get(OPTIMIZED_FUNCTIONS_LIST); | 314 return get(OPTIMIZED_FUNCTIONS_LIST); |
315 } | 315 } |
316 | 316 |
317 | 317 |
318 void Context::AddOptimizedCode(Code* code) { | 318 void Context::AddOptimizedCode(Code* code) { |
319 ASSERT(IsNativeContext()); | 319 DCHECK(IsNativeContext()); |
320 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); | 320 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); |
321 ASSERT(code->next_code_link()->IsUndefined()); | 321 DCHECK(code->next_code_link()->IsUndefined()); |
322 code->set_next_code_link(get(OPTIMIZED_CODE_LIST)); | 322 code->set_next_code_link(get(OPTIMIZED_CODE_LIST)); |
323 set(OPTIMIZED_CODE_LIST, code); | 323 set(OPTIMIZED_CODE_LIST, code); |
324 } | 324 } |
325 | 325 |
326 | 326 |
327 void Context::SetOptimizedCodeListHead(Object* head) { | 327 void Context::SetOptimizedCodeListHead(Object* head) { |
328 ASSERT(IsNativeContext()); | 328 DCHECK(IsNativeContext()); |
329 set(OPTIMIZED_CODE_LIST, head); | 329 set(OPTIMIZED_CODE_LIST, head); |
330 } | 330 } |
331 | 331 |
332 | 332 |
333 Object* Context::OptimizedCodeListHead() { | 333 Object* Context::OptimizedCodeListHead() { |
334 ASSERT(IsNativeContext()); | 334 DCHECK(IsNativeContext()); |
335 return get(OPTIMIZED_CODE_LIST); | 335 return get(OPTIMIZED_CODE_LIST); |
336 } | 336 } |
337 | 337 |
338 | 338 |
339 void Context::SetDeoptimizedCodeListHead(Object* head) { | 339 void Context::SetDeoptimizedCodeListHead(Object* head) { |
340 ASSERT(IsNativeContext()); | 340 DCHECK(IsNativeContext()); |
341 set(DEOPTIMIZED_CODE_LIST, head); | 341 set(DEOPTIMIZED_CODE_LIST, head); |
342 } | 342 } |
343 | 343 |
344 | 344 |
345 Object* Context::DeoptimizedCodeListHead() { | 345 Object* Context::DeoptimizedCodeListHead() { |
346 ASSERT(IsNativeContext()); | 346 DCHECK(IsNativeContext()); |
347 return get(DEOPTIMIZED_CODE_LIST); | 347 return get(DEOPTIMIZED_CODE_LIST); |
348 } | 348 } |
349 | 349 |
350 | 350 |
351 Handle<Object> Context::ErrorMessageForCodeGenerationFromStrings() { | 351 Handle<Object> Context::ErrorMessageForCodeGenerationFromStrings() { |
352 Isolate* isolate = GetIsolate(); | 352 Isolate* isolate = GetIsolate(); |
353 Handle<Object> result(error_message_for_code_gen_from_strings(), isolate); | 353 Handle<Object> result(error_message_for_code_gen_from_strings(), isolate); |
354 if (!result->IsUndefined()) return result; | 354 if (!result->IsUndefined()) return result; |
355 return isolate->factory()->NewStringFromStaticAscii( | 355 return isolate->factory()->NewStringFromStaticAscii( |
356 "Code generation from strings disallowed for this context"); | 356 "Code generation from strings disallowed for this context"); |
(...skipping 16 matching lines...) Expand all Loading... |
373 bool Context::IsBootstrappingOrGlobalObject(Isolate* isolate, Object* object) { | 373 bool Context::IsBootstrappingOrGlobalObject(Isolate* isolate, Object* object) { |
374 // During bootstrapping we allow all objects to pass as global | 374 // During bootstrapping we allow all objects to pass as global |
375 // objects. This is necessary to fix circular dependencies. | 375 // objects. This is necessary to fix circular dependencies. |
376 return isolate->heap()->gc_state() != Heap::NOT_IN_GC || | 376 return isolate->heap()->gc_state() != Heap::NOT_IN_GC || |
377 isolate->bootstrapper()->IsActive() || | 377 isolate->bootstrapper()->IsActive() || |
378 object->IsGlobalObject(); | 378 object->IsGlobalObject(); |
379 } | 379 } |
380 #endif | 380 #endif |
381 | 381 |
382 } } // namespace v8::internal | 382 } } // namespace v8::internal |
OLD | NEW |