| OLD | NEW |
| 1 // Copyright 2011 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 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 // Consider sorting them according to type as well? | 48 // Consider sorting them according to type as well? |
| 49 return x - y; | 49 return x - y; |
| 50 } | 50 } |
| 51 | 51 |
| 52 | 52 |
| 53 template<class Allocator> | 53 template<class Allocator> |
| 54 ScopeInfo<Allocator>::ScopeInfo(Scope* scope) | 54 ScopeInfo<Allocator>::ScopeInfo(Scope* scope) |
| 55 : function_name_(FACTORY->empty_symbol()), | 55 : function_name_(FACTORY->empty_symbol()), |
| 56 calls_eval_(scope->calls_eval()), | 56 calls_eval_(scope->calls_eval()), |
| 57 is_strict_mode_(scope->is_strict_mode()), | 57 is_strict_mode_(scope->is_strict_mode()), |
| 58 type_(scope->type()), |
| 59 source_beg_statement_pos_(scope->SourceBegStatementPos()), |
| 60 source_end_statement_pos_(scope->SourceEndStatementPos()), |
| 61 first_stack_index_(-1), |
| 58 parameters_(scope->num_parameters()), | 62 parameters_(scope->num_parameters()), |
| 59 stack_slots_(scope->num_stack_slots()), | 63 stack_slots_(scope->num_stack_slots()), |
| 60 context_slots_(scope->num_heap_slots()), | 64 context_slots_(scope->num_heap_slots()), |
| 61 context_modes_(scope->num_heap_slots()) { | 65 context_modes_(scope->num_heap_slots()), |
| 66 inner_scopeinfos_(scope->InnerScopes()->length()) { |
| 62 // Add parameters. | 67 // Add parameters. |
| 63 for (int i = 0; i < scope->num_parameters(); i++) { | 68 for (int i = 0; i < scope->num_parameters(); i++) { |
| 64 ASSERT(parameters_.length() == i); | 69 ASSERT(parameters_.length() == i); |
| 65 parameters_.Add(scope->parameter(i)->name()); | 70 parameters_.Add(scope->parameter(i)->name()); |
| 66 } | 71 } |
| 67 | 72 |
| 68 // Add stack locals and collect heap locals. | 73 // Add stack locals and collect heap locals. |
| 69 // We are assuming that the locals' slots are allocated in | 74 // We are assuming that the locals' slots are allocated in |
| 70 // increasing order, so we can simply add them to the | 75 // increasing order, so we can simply add them to the |
| 71 // ScopeInfo lists. However, due to usage analysis, this is | 76 // ScopeInfo lists. However, due to usage analysis, this is |
| (...skipping 15 matching lines...) Expand all Loading... |
| 87 Variable* var = locals[i]; | 92 Variable* var = locals[i]; |
| 88 if (var->is_used()) { | 93 if (var->is_used()) { |
| 89 Slot* slot = var->AsSlot(); | 94 Slot* slot = var->AsSlot(); |
| 90 if (slot != NULL) { | 95 if (slot != NULL) { |
| 91 switch (slot->type()) { | 96 switch (slot->type()) { |
| 92 case Slot::PARAMETER: | 97 case Slot::PARAMETER: |
| 93 // explicitly added to parameters_ above - ignore | 98 // explicitly added to parameters_ above - ignore |
| 94 break; | 99 break; |
| 95 | 100 |
| 96 case Slot::LOCAL: | 101 case Slot::LOCAL: |
| 97 ASSERT(stack_slots_.length() == slot->index()); | 102 if (first_stack_index_ < 0) first_stack_index_ = slot->index(); |
| 103 ASSERT(stack_slots_.length() + first_stack_index_ == slot->index()); |
| 98 stack_slots_.Add(var->name()); | 104 stack_slots_.Add(var->name()); |
| 99 break; | 105 break; |
| 100 | 106 |
| 101 case Slot::CONTEXT: | 107 case Slot::CONTEXT: |
| 102 heap_locals.Add(var); | 108 heap_locals.Add(var); |
| 103 break; | 109 break; |
| 104 | 110 |
| 105 case Slot::LOOKUP: | 111 case Slot::LOOKUP: |
| 106 // This is currently not used. | 112 // This is currently not used. |
| 107 UNREACHABLE(); | 113 UNREACHABLE(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 // Contexts::Lookup() function. Thus record an empty symbol here so we | 147 // Contexts::Lookup() function. Thus record an empty symbol here so we |
| 142 // get the correct number of context slots. | 148 // get the correct number of context slots. |
| 143 ASSERT(var->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS == | 149 ASSERT(var->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS == |
| 144 context_slots_.length()); | 150 context_slots_.length()); |
| 145 ASSERT(var->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS == | 151 ASSERT(var->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS == |
| 146 context_modes_.length()); | 152 context_modes_.length()); |
| 147 context_slots_.Add(FACTORY->empty_symbol()); | 153 context_slots_.Add(FACTORY->empty_symbol()); |
| 148 context_modes_.Add(Variable::INTERNAL); | 154 context_modes_.Add(Variable::INTERNAL); |
| 149 } | 155 } |
| 150 } | 156 } |
| 157 |
| 158 // Add inner scope information. |
| 159 ZoneList<Scope*>* inner_scopes = scope->InnerScopes(); |
| 160 for (int i = 0; i < inner_scopes->length(); i++) { |
| 161 if (!inner_scopes->at(i)->is_catch_scope() && |
| 162 !inner_scopes->at(i)->is_with_scope()) continue; |
| 163 inner_scopeinfos_.Add(SerializedScopeInfo::Create(inner_scopes->at(i))); |
| 164 } |
| 151 } | 165 } |
| 152 | 166 |
| 153 | 167 |
| 154 // Encoding format in a FixedArray object: | 168 // Encoding format in a FixedArray object: |
| 155 // | 169 // |
| 156 // - function name | 170 // - function name |
| 157 // | 171 // |
| 158 // - calls eval boolean flag | 172 // - calls eval boolean flag |
| 159 // | 173 // |
| 174 // - strict scope boolean flag |
| 175 // |
| 176 // - scope type |
| 177 // |
| 178 // - start statement position |
| 179 // |
| 180 // - end statement position |
| 181 // |
| 182 // - first stack index for stack slots |
| 183 // |
| 160 // - number of variables in the context object (smi) (= function context | 184 // - number of variables in the context object (smi) (= function context |
| 161 // slot index + 1) | 185 // slot index + 1) |
| 162 // - list of pairs (name, Var mode) of context-allocated variables (starting | 186 // - list of pairs (name, Var mode) of context-allocated variables (starting |
| 163 // with context slot 0) | 187 // with context slot 0) |
| 164 // | 188 // |
| 165 // - number of parameters (smi) | 189 // - number of parameters (smi) |
| 166 // - list of parameter names (starting with parameter 0 first) | 190 // - list of parameter names (starting with parameter 0 first) |
| 167 // | 191 // |
| 168 // - number of variables on the stack (smi) | 192 // - number of variables on the stack (smi) |
| 169 // - list of names of stack-allocated variables (starting with stack slot 0) | 193 // - list of names of stack-allocated variables (starting with stack slot 0) |
| 194 // |
| 195 // - number of immediate nested scopes (smi) |
| 196 // - list of handles to serialized scope infos for nested scopes |
| 170 | 197 |
| 171 // The ScopeInfo representation could be simplified and the ScopeInfo | 198 // The ScopeInfo representation could be simplified and the ScopeInfo |
| 172 // re-implemented (with almost the same interface). Here is a | 199 // re-implemented (with almost the same interface). Here is a |
| 173 // suggestion for the new format: | 200 // suggestion for the new format: |
| 174 // | 201 // |
| 175 // - have a single list with all variable names (parameters, stack locals, | 202 // - have a single list with all variable names (parameters, stack locals, |
| 176 // context locals), followed by a list of non-Object* values containing | 203 // context locals), followed by a list of non-Object* values containing |
| 177 // the variables information (what kind, index, attributes) | 204 // the variables information (what kind, index, attributes) |
| 178 // - searching the linear list of names is fast and yields an index into the | 205 // - searching the linear list of names is fast and yields an index into the |
| 179 // list if the variable name is found | 206 // list if the variable name is found |
| 180 // - that list index is then used to find the variable information in the | 207 // - that list index is then used to find the variable information in the |
| 181 // subsequent list | 208 // subsequent list |
| 182 // - the list entries don't have to be in any particular order, so all the | 209 // - the list entries don't have to be in any particular order, so all the |
| 183 // current sorting business can go away | 210 // current sorting business can go away |
| 184 // - the ScopeInfo lookup routines can be reduced to perhaps a single lookup | 211 // - the ScopeInfo lookup routines can be reduced to perhaps a single lookup |
| 185 // which returns all information at once | 212 // which returns all information at once |
| 186 // - when gathering the information from a Scope, we only need to iterate | 213 // - when gathering the information from a Scope, we only need to iterate |
| 187 // through the local variables (parameters and context info is already | 214 // through the local variables (parameters and context info is already |
| 188 // present) | 215 // present) |
| 189 | 216 |
| 190 | 217 |
| 191 static inline Object** ReadInt(Object** p, int* x) { | 218 template <class T> |
| 192 *x = (reinterpret_cast<Smi*>(*p++))->value(); | 219 static inline Object** ReadInt(Object** p, T* x) { |
| 220 *x = static_cast<T>((reinterpret_cast<Smi*>(*p++))->value()); |
| 193 return p; | 221 return p; |
| 194 } | 222 } |
| 195 | 223 |
| 196 | 224 |
| 197 static inline Object** ReadBool(Object** p, bool* x) { | 225 static inline Object** ReadBool(Object** p, bool* x) { |
| 198 *x = (reinterpret_cast<Smi*>(*p++))->value() != 0; | 226 *x = (reinterpret_cast<Smi*>(*p++))->value() != 0; |
| 199 return p; | 227 return p; |
| 200 } | 228 } |
| 201 | 229 |
| 202 | 230 |
| 203 static inline Object** ReadSymbol(Object** p, Handle<String>* s) { | 231 template <class T> |
| 204 *s = Handle<String>(reinterpret_cast<String*>(*p++)); | 232 static inline Object** ReadSymbol(Object** p, Handle<T>* s) { |
| 233 *s = Handle<T>(reinterpret_cast<T*>(*p++)); |
| 205 return p; | 234 return p; |
| 206 } | 235 } |
| 207 | 236 |
| 208 | 237 |
| 209 template <class Allocator> | 238 template <class Allocator, class T> |
| 210 static Object** ReadList(Object** p, List<Handle<String>, Allocator >* list) { | 239 static Object** ReadList(Object** p, List<Handle<T>, Allocator >* list) { |
| 211 ASSERT(list->is_empty()); | 240 ASSERT(list->is_empty()); |
| 212 int n; | 241 int n; |
| 213 p = ReadInt(p, &n); | 242 p = ReadInt(p, &n); |
| 214 while (n-- > 0) { | 243 while (n-- > 0) { |
| 215 Handle<String> s; | 244 Handle<T> s; |
| 216 p = ReadSymbol(p, &s); | 245 p = ReadSymbol(p, &s); |
| 217 list->Add(s); | 246 list->Add(s); |
| 218 } | 247 } |
| 219 return p; | 248 return p; |
| 220 } | 249 } |
| 221 | 250 |
| 222 | 251 |
| 223 template <class Allocator> | 252 template <class Allocator> |
| 224 static Object** ReadList(Object** p, | 253 static Object** ReadList(Object** p, |
| 225 List<Handle<String>, Allocator>* list, | 254 List<Handle<String>, Allocator>* list, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 238 return p; | 267 return p; |
| 239 } | 268 } |
| 240 | 269 |
| 241 | 270 |
| 242 template<class Allocator> | 271 template<class Allocator> |
| 243 ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data) | 272 ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data) |
| 244 : function_name_(FACTORY->empty_symbol()), | 273 : function_name_(FACTORY->empty_symbol()), |
| 245 parameters_(4), | 274 parameters_(4), |
| 246 stack_slots_(8), | 275 stack_slots_(8), |
| 247 context_slots_(8), | 276 context_slots_(8), |
| 248 context_modes_(8) { | 277 context_modes_(8), |
| 278 inner_scopeinfos_(4) { |
| 249 if (data->length() > 0) { | 279 if (data->length() > 0) { |
| 250 Object** p0 = data->data_start(); | 280 Object** p0 = data->data_start(); |
| 251 Object** p = p0; | 281 Object** p = p0; |
| 252 p = ReadSymbol(p, &function_name_); | 282 p = ReadSymbol(p, &function_name_); |
| 253 p = ReadBool(p, &calls_eval_); | 283 p = ReadBool(p, &calls_eval_); |
| 254 p = ReadBool(p, &is_strict_mode_); | 284 p = ReadBool(p, &is_strict_mode_); |
| 285 p = ReadInt(p, &type_); |
| 286 p = ReadInt(p, &source_beg_statement_pos_); |
| 287 p = ReadInt(p, &source_end_statement_pos_); |
| 288 p = ReadInt(p, &first_stack_index_); |
| 255 p = ReadList<Allocator>(p, &context_slots_, &context_modes_); | 289 p = ReadList<Allocator>(p, &context_slots_, &context_modes_); |
| 256 p = ReadList<Allocator>(p, ¶meters_); | 290 p = ReadList<Allocator>(p, ¶meters_); |
| 257 p = ReadList<Allocator>(p, &stack_slots_); | 291 p = ReadList<Allocator>(p, &stack_slots_); |
| 292 p = ReadList<Allocator>(p, &inner_scopeinfos_); |
| 258 ASSERT((p - p0) == FixedArray::cast(data)->length()); | 293 ASSERT((p - p0) == FixedArray::cast(data)->length()); |
| 259 } | 294 } |
| 260 } | 295 } |
| 261 | 296 |
| 262 | 297 |
| 263 static inline Object** WriteInt(Object** p, int x) { | 298 static inline Object** WriteInt(Object** p, int x) { |
| 264 *p++ = Smi::FromInt(x); | 299 *p++ = Smi::FromInt(x); |
| 265 return p; | 300 return p; |
| 266 } | 301 } |
| 267 | 302 |
| 268 | 303 |
| 269 static inline Object** WriteBool(Object** p, bool b) { | 304 static inline Object** WriteBool(Object** p, bool b) { |
| 270 *p++ = Smi::FromInt(b ? 1 : 0); | 305 *p++ = Smi::FromInt(b ? 1 : 0); |
| 271 return p; | 306 return p; |
| 272 } | 307 } |
| 273 | 308 |
| 274 | 309 |
| 275 static inline Object** WriteSymbol(Object** p, Handle<String> s) { | 310 template <class T> |
| 311 static inline Object** WriteSymbol(Object** p, Handle<T> s) { |
| 276 *p++ = *s; | 312 *p++ = *s; |
| 277 return p; | 313 return p; |
| 278 } | 314 } |
| 279 | 315 |
| 280 | 316 |
| 281 template <class Allocator> | 317 template <class Allocator, class T> |
| 282 static Object** WriteList(Object** p, List<Handle<String>, Allocator >* list) { | 318 static Object** WriteList(Object** p, List<Handle<T>, Allocator >* list) { |
| 283 const int n = list->length(); | 319 const int n = list->length(); |
| 284 p = WriteInt(p, n); | 320 p = WriteInt(p, n); |
| 285 for (int i = 0; i < n; i++) { | 321 for (int i = 0; i < n; i++) { |
| 286 p = WriteSymbol(p, list->at(i)); | 322 p = WriteSymbol(p, list->at(i)); |
| 287 } | 323 } |
| 288 return p; | 324 return p; |
| 289 } | 325 } |
| 290 | 326 |
| 291 | 327 |
| 292 template <class Allocator> | 328 template <class Allocator> |
| 293 static Object** WriteList(Object** p, | 329 static Object** WriteList(Object** p, |
| 294 List<Handle<String>, Allocator>* list, | 330 List<Handle<String>, Allocator>* list, |
| 295 List<Variable::Mode, Allocator>* modes) { | 331 List<Variable::Mode, Allocator>* modes) { |
| 296 const int n = list->length(); | 332 const int n = list->length(); |
| 297 p = WriteInt(p, n); | 333 p = WriteInt(p, n); |
| 298 for (int i = 0; i < n; i++) { | 334 for (int i = 0; i < n; i++) { |
| 299 p = WriteSymbol(p, list->at(i)); | 335 p = WriteSymbol(p, list->at(i)); |
| 300 p = WriteInt(p, modes->at(i)); | 336 p = WriteInt(p, modes->at(i)); |
| 301 } | 337 } |
| 302 return p; | 338 return p; |
| 303 } | 339 } |
| 304 | 340 |
| 305 | 341 |
| 306 template<class Allocator> | 342 template<class Allocator> |
| 307 Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() { | 343 Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() { |
| 308 // function name, calls eval, is_strict_mode, length for 3 tables: | 344 // function name, calls eval, scope type, is_strict_mode, source beg pos, |
| 309 const int extra_slots = 1 + 1 + 1 + 3; | 345 // source end pos, first stack slot, length for 4 tables: |
| 346 const int extra_slots = 1 + 1 + 1 + 1 + 1 + 1 + 1 + 4; |
| 310 int length = extra_slots + | 347 int length = extra_slots + |
| 311 context_slots_.length() * 2 + | 348 context_slots_.length() * 2 + |
| 312 parameters_.length() + | 349 parameters_.length() + |
| 313 stack_slots_.length(); | 350 stack_slots_.length() + |
| 351 inner_scopeinfos_.length(); |
| 314 | 352 |
| 315 Handle<SerializedScopeInfo> data( | 353 Handle<SerializedScopeInfo> data( |
| 316 SerializedScopeInfo::cast(*FACTORY->NewFixedArray(length, TENURED))); | 354 SerializedScopeInfo::cast(*FACTORY->NewFixedArray(length, TENURED))); |
| 317 AssertNoAllocation nogc; | 355 AssertNoAllocation nogc; |
| 318 | 356 |
| 319 Object** p0 = data->data_start(); | 357 Object** p0 = data->data_start(); |
| 320 Object** p = p0; | 358 Object** p = p0; |
| 321 p = WriteSymbol(p, function_name_); | 359 p = WriteSymbol(p, function_name_); |
| 322 p = WriteBool(p, calls_eval_); | 360 p = WriteBool(p, calls_eval_); |
| 323 p = WriteBool(p, is_strict_mode_); | 361 p = WriteBool(p, is_strict_mode_); |
| 362 p = WriteInt(p, type_); |
| 363 p = WriteInt(p, source_beg_statement_pos_); |
| 364 p = WriteInt(p, source_end_statement_pos_); |
| 365 p = WriteInt(p, first_stack_index_); |
| 324 p = WriteList(p, &context_slots_, &context_modes_); | 366 p = WriteList(p, &context_slots_, &context_modes_); |
| 325 p = WriteList(p, ¶meters_); | 367 p = WriteList(p, ¶meters_); |
| 326 p = WriteList(p, &stack_slots_); | 368 p = WriteList(p, &stack_slots_); |
| 369 p = WriteList(p, &inner_scopeinfos_); |
| 327 ASSERT((p - p0) == length); | 370 ASSERT((p - p0) == length); |
| 328 | 371 |
| 329 return data; | 372 return data; |
| 330 } | 373 } |
| 331 | 374 |
| 332 | 375 |
| 333 template<class Allocator> | 376 template<class Allocator> |
| 334 Handle<String> ScopeInfo<Allocator>::LocalName(int i) const { | 377 Handle<String> ScopeInfo<Allocator>::LocalName(int i) const { |
| 335 // A local variable can be allocated either on the stack or in the context. | 378 // A local variable can be allocated either on the stack or in the context. |
| 336 // For variables allocated in the context they are always preceded by | 379 // For variables allocated in the context they are always preceded by |
| (...skipping 24 matching lines...) Expand all Loading... |
| 361 } | 404 } |
| 362 | 405 |
| 363 | 406 |
| 364 SerializedScopeInfo* SerializedScopeInfo::Empty() { | 407 SerializedScopeInfo* SerializedScopeInfo::Empty() { |
| 365 return reinterpret_cast<SerializedScopeInfo*>(HEAP->empty_fixed_array()); | 408 return reinterpret_cast<SerializedScopeInfo*>(HEAP->empty_fixed_array()); |
| 366 } | 409 } |
| 367 | 410 |
| 368 | 411 |
| 369 Object** SerializedScopeInfo::ContextEntriesAddr() { | 412 Object** SerializedScopeInfo::ContextEntriesAddr() { |
| 370 ASSERT(length() > 0); | 413 ASSERT(length() > 0); |
| 371 // +3 for function name, calls eval, strict mode. | 414 // +6 for function name, calls eval, strict mode, scope type, source beg pos, |
| 372 return data_start() + 3; | 415 // source end pos, first stack slot. |
| 416 return data_start() + 7; |
| 373 } | 417 } |
| 374 | 418 |
| 375 | 419 |
| 376 Object** SerializedScopeInfo::ParameterEntriesAddr() { | 420 Object** SerializedScopeInfo::ParameterEntriesAddr() { |
| 377 ASSERT(length() > 0); | 421 ASSERT(length() > 0); |
| 378 Object** p = ContextEntriesAddr(); | 422 Object** p = ContextEntriesAddr(); |
| 379 int number_of_context_slots; | 423 int number_of_context_slots; |
| 380 p = ReadInt(p, &number_of_context_slots); | 424 p = ReadInt(p, &number_of_context_slots); |
| 381 return p + number_of_context_slots*2; // *2 for pairs | 425 return p + number_of_context_slots*2; // *2 for pairs |
| 382 } | 426 } |
| 383 | 427 |
| 384 | 428 |
| 385 Object** SerializedScopeInfo::StackSlotEntriesAddr() { | 429 Object** SerializedScopeInfo::StackSlotEntriesAddr() { |
| 386 ASSERT(length() > 0); | 430 ASSERT(length() > 0); |
| 387 Object** p = ParameterEntriesAddr(); | 431 Object** p = ParameterEntriesAddr(); |
| 388 int number_of_parameter_slots; | 432 int number_of_parameter_slots; |
| 389 p = ReadInt(p, &number_of_parameter_slots); | 433 p = ReadInt(p, &number_of_parameter_slots); |
| 390 return p + number_of_parameter_slots; | 434 return p + number_of_parameter_slots; |
| 391 } | 435 } |
| 392 | 436 |
| 393 | 437 |
| 438 Object** SerializedScopeInfo::NestedScopeEntriesAddr() { |
| 439 ASSERT(length() > 0); |
| 440 Object** p = StackSlotEntriesAddr(); |
| 441 int number_of_stack_slots; |
| 442 p = ReadInt(p, &number_of_stack_slots); |
| 443 return p + number_of_stack_slots; |
| 444 } |
| 445 |
| 446 |
| 447 |
| 394 bool SerializedScopeInfo::CallsEval() { | 448 bool SerializedScopeInfo::CallsEval() { |
| 395 if (length() > 0) { | 449 if (length() > 0) { |
| 396 Object** p = data_start() + 1; // +1 for function name. | 450 Object** p = data_start() + 1; // +1 for function name. |
| 397 bool calls_eval; | 451 bool calls_eval; |
| 398 p = ReadBool(p, &calls_eval); | 452 p = ReadBool(p, &calls_eval); |
| 399 return calls_eval; | 453 return calls_eval; |
| 400 } | 454 } |
| 401 return false; | 455 return false; |
| 402 } | 456 } |
| 403 | 457 |
| 404 | 458 |
| 405 bool SerializedScopeInfo::IsStrictMode() { | 459 bool SerializedScopeInfo::IsStrictMode() { |
| 406 if (length() > 0) { | 460 if (length() > 0) { |
| 407 Object** p = data_start() + 2; // +2 for function name, calls eval. | 461 Object** p = data_start() + 2; // +2 for function name, calls eval. |
| 408 bool strict_mode; | 462 bool strict_mode; |
| 409 p = ReadBool(p, &strict_mode); | 463 p = ReadBool(p, &strict_mode); |
| 410 return strict_mode; | 464 return strict_mode; |
| 411 } | 465 } |
| 412 return false; | 466 return false; |
| 413 } | 467 } |
| 414 | 468 |
| 415 | 469 |
| 470 Scope::Type SerializedScopeInfo::ScopeType() { |
| 471 ASSERT(length() > 0); |
| 472 // +3 for function name, calls eval, strict mode. |
| 473 Object** p = data_start() + 3; |
| 474 Scope::Type type; |
| 475 p = ReadInt(p, &type); |
| 476 return type; |
| 477 } |
| 478 |
| 479 |
| 480 int SerializedScopeInfo::SourceBegStatementPos() { |
| 481 if (length() > 0) { |
| 482 // +4 for function name, calls eval, strict mode, scope type. |
| 483 Object** p = data_start() + 4; |
| 484 int source_beg_statement_pos; |
| 485 p = ReadInt(p, &source_beg_statement_pos); |
| 486 return source_beg_statement_pos; |
| 487 } |
| 488 return -1; |
| 489 } |
| 490 |
| 491 |
| 492 int SerializedScopeInfo::SourceEndStatementPos() { |
| 493 if (length() > 0) { |
| 494 // +5 for function name, calls eval, strict mode, scope type, |
| 495 // source beg pos. |
| 496 Object** p = data_start() + 5; |
| 497 int source_end_statement_pos; |
| 498 p = ReadInt(p, &source_end_statement_pos); |
| 499 return source_end_statement_pos; |
| 500 } |
| 501 return -1; |
| 502 } |
| 503 |
| 504 |
| 505 int SerializedScopeInfo::FirstStackSlot() { |
| 506 if (length() > 0) { |
| 507 // +6 for function name, calls eval, strict mode, scope type, |
| 508 // source beg pos, source end pos. |
| 509 Object** p = data_start() + 6; |
| 510 int source_end_pos; |
| 511 p = ReadInt(p, &source_end_pos); |
| 512 return source_end_pos; |
| 513 } |
| 514 return -1; |
| 515 } |
| 516 |
| 517 |
| 416 int SerializedScopeInfo::NumberOfStackSlots() { | 518 int SerializedScopeInfo::NumberOfStackSlots() { |
| 417 if (length() > 0) { | 519 if (length() > 0) { |
| 418 Object** p = StackSlotEntriesAddr(); | 520 Object** p = StackSlotEntriesAddr(); |
| 419 int number_of_stack_slots; | 521 int number_of_stack_slots; |
| 420 ReadInt(p, &number_of_stack_slots); | 522 ReadInt(p, &number_of_stack_slots); |
| 421 return number_of_stack_slots; | 523 return number_of_stack_slots; |
| 422 } | 524 } |
| 423 return 0; | 525 return 0; |
| 424 } | 526 } |
| 425 | 527 |
| 426 | 528 |
| 427 int SerializedScopeInfo::NumberOfContextSlots() { | 529 int SerializedScopeInfo::NumberOfContextSlots() { |
| 428 if (length() > 0) { | 530 if (length() > 0) { |
| 429 Object** p = ContextEntriesAddr(); | 531 Object** p = ContextEntriesAddr(); |
| 430 int number_of_context_slots; | 532 int number_of_context_slots; |
| 431 ReadInt(p, &number_of_context_slots); | 533 ReadInt(p, &number_of_context_slots); |
| 432 return number_of_context_slots + Context::MIN_CONTEXT_SLOTS; | 534 return number_of_context_slots + Context::MIN_CONTEXT_SLOTS; |
| 433 } | 535 } |
| 434 return 0; | 536 return 0; |
| 435 } | 537 } |
| 436 | 538 |
| 437 | 539 |
| 540 int SerializedScopeInfo::NumberOfNestedScopes() { |
| 541 if (length() > 0) { |
| 542 Object** p = NestedScopeEntriesAddr(); |
| 543 int number_of_nested_scopes; |
| 544 ReadInt(p, &number_of_nested_scopes); |
| 545 return number_of_nested_scopes; |
| 546 } |
| 547 return 0; |
| 548 } |
| 549 |
| 550 |
| 551 Handle<SerializedScopeInfo> SerializedScopeInfo::NestedScope(int i) { |
| 552 ASSERT(0 <= i && i < NumberOfNestedScopes()); |
| 553 Object* p = *(NestedScopeEntriesAddr() + i + 1); |
| 554 return Handle<SerializedScopeInfo>(reinterpret_cast<SerializedScopeInfo*>(p)); |
| 555 } |
| 556 |
| 557 |
| 438 bool SerializedScopeInfo::HasHeapAllocatedLocals() { | 558 bool SerializedScopeInfo::HasHeapAllocatedLocals() { |
| 439 if (length() > 0) { | 559 if (length() > 0) { |
| 440 Object** p = ContextEntriesAddr(); | 560 Object** p = ContextEntriesAddr(); |
| 441 int number_of_context_slots; | 561 int number_of_context_slots; |
| 442 ReadInt(p, &number_of_context_slots); | 562 ReadInt(p, &number_of_context_slots); |
| 443 return number_of_context_slots > 0; | 563 return number_of_context_slots > 0; |
| 444 } | 564 } |
| 445 return false; | 565 return false; |
| 446 } | 566 } |
| 447 | 567 |
| 448 | 568 |
| 569 bool SerializedScopeInfo::HasContext() { |
| 570 return ScopeType() == Scope::WITH_SCOPE || |
| 571 ScopeType() == Scope::GLOBAL_SCOPE || |
| 572 HasHeapAllocatedLocals(); |
| 573 } |
| 574 |
| 575 |
| 449 int SerializedScopeInfo::StackSlotIndex(String* name) { | 576 int SerializedScopeInfo::StackSlotIndex(String* name) { |
| 450 ASSERT(name->IsSymbol()); | 577 ASSERT(name->IsSymbol()); |
| 451 if (length() > 0) { | 578 if (length() > 0) { |
| 452 // Slots start after length entry. | 579 // Slots start after length entry. |
| 453 Object** p0 = StackSlotEntriesAddr(); | 580 Object** p0 = StackSlotEntriesAddr(); |
| 454 int number_of_stack_slots; | 581 int number_of_stack_slots; |
| 455 p0 = ReadInt(p0, &number_of_stack_slots); | 582 p0 = ReadInt(p0, &number_of_stack_slots); |
| 456 Object** p = p0; | 583 Object** p = p0; |
| 457 Object** end = p0 + number_of_stack_slots; | 584 Object** end = p0 + number_of_stack_slots; |
| 458 while (p != end) { | 585 while (p != end) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 ReadInt(p, &number_of_context_slots); | 657 ReadInt(p, &number_of_context_slots); |
| 531 ASSERT(number_of_context_slots != 0); | 658 ASSERT(number_of_context_slots != 0); |
| 532 // The function context slot is the last entry. | 659 // The function context slot is the last entry. |
| 533 return number_of_context_slots + Context::MIN_CONTEXT_SLOTS - 1; | 660 return number_of_context_slots + Context::MIN_CONTEXT_SLOTS - 1; |
| 534 } | 661 } |
| 535 } | 662 } |
| 536 return -1; | 663 return -1; |
| 537 } | 664 } |
| 538 | 665 |
| 539 | 666 |
| 667 void SerializedScopeInfo::GetLocalScopeChain( |
| 668 List<Handle<SerializedScopeInfo> >* chain, |
| 669 int position) { |
| 670 chain->Add(Handle<SerializedScopeInfo>(this)); |
| 671 |
| 672 for (int i = 0; i < NumberOfNestedScopes(); i++) { |
| 673 Handle<SerializedScopeInfo> scope = NestedScope(i); |
| 674 int beg_pos = scope->SourceBegStatementPos(); |
| 675 int end_pos = scope->SourceEndStatementPos(); |
| 676 ASSERT(beg_pos >= 0 && end_pos >= 0); |
| 677 if (beg_pos <= position && position <= end_pos) { |
| 678 scope->GetLocalScopeChain(chain, position); |
| 679 return; |
| 680 } |
| 681 } |
| 682 } |
| 683 |
| 684 |
| 540 int ContextSlotCache::Hash(Object* data, String* name) { | 685 int ContextSlotCache::Hash(Object* data, String* name) { |
| 541 // Uses only lower 32 bits if pointers are larger. | 686 // Uses only lower 32 bits if pointers are larger. |
| 542 uintptr_t addr_hash = | 687 uintptr_t addr_hash = |
| 543 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; | 688 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; |
| 544 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); | 689 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); |
| 545 } | 690 } |
| 546 | 691 |
| 547 | 692 |
| 548 int ContextSlotCache::Lookup(Object* data, | 693 int ContextSlotCache::Lookup(Object* data, |
| 549 String* name, | 694 String* name, |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 } | 784 } |
| 640 #endif // DEBUG | 785 #endif // DEBUG |
| 641 | 786 |
| 642 | 787 |
| 643 // Make sure the classes get instantiated by the template system. | 788 // Make sure the classes get instantiated by the template system. |
| 644 template class ScopeInfo<FreeStoreAllocationPolicy>; | 789 template class ScopeInfo<FreeStoreAllocationPolicy>; |
| 645 template class ScopeInfo<PreallocatedStorage>; | 790 template class ScopeInfo<PreallocatedStorage>; |
| 646 template class ScopeInfo<ZoneListAllocationPolicy>; | 791 template class ScopeInfo<ZoneListAllocationPolicy>; |
| 647 | 792 |
| 648 } } // namespace v8::internal | 793 } } // namespace v8::internal |
| OLD | NEW |