v8  3.25.30(node0.11.13)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
handles.cc
Go to the documentation of this file.
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 "accessors.h"
31 #include "api.h"
32 #include "arguments.h"
33 #include "bootstrapper.h"
34 #include "compiler.h"
35 #include "debug.h"
36 #include "execution.h"
37 #include "global-handles.h"
38 #include "natives.h"
39 #include "runtime.h"
40 #include "string-search.h"
41 #include "stub-cache.h"
42 #include "vm-state-inl.h"
43 
44 namespace v8 {
45 namespace internal {
46 
47 
50  int n = impl->blocks()->length();
51  if (n == 0) return 0;
52  return ((n - 1) * kHandleBlockSize) + static_cast<int>(
53  (isolate->handle_scope_data()->next - impl->blocks()->last()));
54 }
55 
56 
57 Object** HandleScope::Extend(Isolate* isolate) {
58  HandleScopeData* current = isolate->handle_scope_data();
59 
60  Object** result = current->next;
61 
62  ASSERT(result == current->limit);
63  // Make sure there's at least one scope on the stack and that the
64  // top of the scope stack isn't a barrier.
65  if (!Utils::ApiCheck(current->level != 0,
66  "v8::HandleScope::CreateHandle()",
67  "Cannot create a handle without a HandleScope")) {
68  return NULL;
69  }
70  HandleScopeImplementer* impl = isolate->handle_scope_implementer();
71  // If there's more room in the last block, we use that. This is used
72  // for fast creation of scopes after scope barriers.
73  if (!impl->blocks()->is_empty()) {
74  Object** limit = &impl->blocks()->last()[kHandleBlockSize];
75  if (current->limit != limit) {
76  current->limit = limit;
77  ASSERT(limit - current->next < kHandleBlockSize);
78  }
79  }
80 
81  // If we still haven't found a slot for the handle, we extend the
82  // current handle scope by allocating a new handle block.
83  if (result == current->limit) {
84  // If there's a spare block, use it for growing the current scope.
85  result = impl->GetSpareOrNewBlock();
86  // Add the extension to the global list of blocks, but count the
87  // extension as part of the current scope.
88  impl->blocks()->Add(result);
89  current->limit = &result[kHandleBlockSize];
90  }
91 
92  return result;
93 }
94 
95 
97  HandleScopeData* current = isolate->handle_scope_data();
98  isolate->handle_scope_implementer()->DeleteExtensions(current->limit);
99 }
100 
101 
102 #ifdef ENABLE_HANDLE_ZAPPING
103 void HandleScope::ZapRange(Object** start, Object** end) {
104  ASSERT(end - start <= kHandleBlockSize);
105  for (Object** p = start; p != end; p++) {
106  *reinterpret_cast<Address*>(p) = v8::internal::kHandleZapValue;
107  }
108 }
109 #endif
110 
111 
113  return reinterpret_cast<Address>(&isolate->handle_scope_data()->level);
114 }
115 
116 
118  return reinterpret_cast<Address>(&isolate->handle_scope_data()->next);
119 }
120 
121 
123  return reinterpret_cast<Address>(&isolate->handle_scope_data()->limit);
124 }
125 
126 
128  Handle<JSArray> array) {
129  CALL_HEAP_FUNCTION(content->GetIsolate(),
130  content->AddKeysFromJSArray(*array), FixedArray);
131 }
132 
133 
135  Handle<FixedArray> second) {
136  CALL_HEAP_FUNCTION(first->GetIsolate(),
137  first->UnionOfKeys(*second), FixedArray);
138 }
139 
140 
142  Handle<JSFunction> constructor,
143  Handle<JSGlobalProxy> global) {
145  constructor->GetIsolate(),
146  constructor->GetHeap()->ReinitializeJSGlobalProxy(*constructor, *global),
147  JSGlobalProxy);
148 }
149 
150 
152  CALL_HEAP_FUNCTION_VOID(string->GetIsolate(), string->TryFlatten());
153 }
154 
155 
157  CALL_HEAP_FUNCTION(string->GetIsolate(), string->TryFlatten(), String);
158 }
159 
160 
162  Handle<Object> key,
163  Handle<Object> value,
164  PropertyAttributes attributes) {
165  return Runtime::ForceSetObjectProperty(object->GetIsolate(), object, key,
166  value, attributes);
167 }
168 
169 
171  Isolate* isolate = object->GetIsolate();
172  CALL_HEAP_FUNCTION(isolate,
174  isolate, object, key, JSReceiver::NORMAL_DELETION),
175  Object);
176 }
177 
178 
180  Handle<Object> key) {
181  Isolate* isolate = object->GetIsolate();
182  CALL_HEAP_FUNCTION(isolate,
184  isolate, object, key, JSReceiver::FORCE_DELETION),
185  Object);
186 }
187 
188 
190  Isolate* isolate = obj->GetIsolate();
191  CALL_HEAP_FUNCTION(isolate,
192  Runtime::HasObjectProperty(isolate, obj, key), Object);
193 }
194 
195 
197  const char* name) {
198  Isolate* isolate = obj->GetIsolate();
199  Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
200  CALL_HEAP_FUNCTION(isolate, obj->GetProperty(*str), Object);
201 }
202 
203 
206  Handle<Object> key) {
207  CALL_HEAP_FUNCTION(isolate,
208  Runtime::GetObjectProperty(isolate, obj, key), Object);
209 }
210 
211 
213  uint32_t index) {
215  isolate,
216  isolate->heap()->LookupSingleCharacterStringFromCode(index),
217  String);
218 }
219 
220 
221 // Wrappers for scripts are kept alive and cached in weak global
222 // handles referred from foreign objects held by the scripts as long as
223 // they are used. When they are not used anymore, the garbage
224 // collector will call the weak callback on the global handle
225 // associated with the wrapper and get rid of both the wrapper and the
226 // handle.
227 static void ClearWrapperCache(
229  Object** location = reinterpret_cast<Object**>(data.GetParameter());
230  JSValue* wrapper = JSValue::cast(*location);
231  Foreign* foreign = Script::cast(wrapper->value())->wrapper();
232  ASSERT_EQ(foreign->foreign_address(), reinterpret_cast<Address>(location));
233  foreign->set_foreign_address(0);
234  GlobalHandles::Destroy(location);
235  Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
236  isolate->counters()->script_wrappers()->Decrement();
237 }
238 
239 
241  if (script->wrapper()->foreign_address() != NULL) {
242  // Return a handle for the existing script wrapper from the cache.
243  return Handle<JSValue>(
244  *reinterpret_cast<JSValue**>(script->wrapper()->foreign_address()));
245  }
246  Isolate* isolate = script->GetIsolate();
247  // Construct a new script wrapper.
248  isolate->counters()->script_wrappers()->Increment();
249  Handle<JSFunction> constructor = isolate->script_function();
250  Handle<JSValue> result =
251  Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
252 
253  // The allocation might have triggered a GC, which could have called this
254  // function recursively, and a wrapper has already been created and cached.
255  // In that case, simply return a handle for the cached wrapper.
256  if (script->wrapper()->foreign_address() != NULL) {
257  return Handle<JSValue>(
258  *reinterpret_cast<JSValue**>(script->wrapper()->foreign_address()));
259  }
260 
261  result->set_value(*script);
262 
263  // Create a new weak global handle and use it to cache the wrapper
264  // for future use. The cache will automatically be cleared by the
265  // garbage collector when it is not used anymore.
266  Handle<Object> handle = isolate->global_handles()->Create(*result);
267  GlobalHandles::MakeWeak(handle.location(),
268  reinterpret_cast<void*>(handle.location()),
269  &ClearWrapperCache);
270  script->wrapper()->set_foreign_address(
271  reinterpret_cast<Address>(handle.location()));
272  return result;
273 }
274 
275 
276 // Init line_ends array with code positions of line ends inside script
277 // source.
279  if (!script->line_ends()->IsUndefined()) return;
280 
281  Isolate* isolate = script->GetIsolate();
282 
283  if (!script->source()->IsString()) {
284  ASSERT(script->source()->IsUndefined());
285  Handle<FixedArray> empty = isolate->factory()->NewFixedArray(0);
286  script->set_line_ends(*empty);
287  ASSERT(script->line_ends()->IsFixedArray());
288  return;
289  }
290 
291  Handle<String> src(String::cast(script->source()), isolate);
292 
293  Handle<FixedArray> array = CalculateLineEnds(src, true);
294 
295  if (*array != isolate->heap()->empty_fixed_array()) {
296  array->set_map(isolate->heap()->fixed_cow_array_map());
297  }
298 
299  script->set_line_ends(*array);
300  ASSERT(script->line_ends()->IsFixedArray());
301 }
302 
303 
304 template <typename SourceChar>
305 static void CalculateLineEnds(Isolate* isolate,
306  List<int>* line_ends,
307  Vector<const SourceChar> src,
308  bool with_last_line) {
309  const int src_len = src.length();
310  StringSearch<uint8_t, SourceChar> search(isolate, STATIC_ASCII_VECTOR("\n"));
311 
312  // Find and record line ends.
313  int position = 0;
314  while (position != -1 && position < src_len) {
315  position = search.Search(src, position);
316  if (position != -1) {
317  line_ends->Add(position);
318  position++;
319  } else if (with_last_line) {
320  // Even if the last line misses a line end, it is counted.
321  line_ends->Add(src_len);
322  return;
323  }
324  }
325 }
326 
327 
328 Handle<FixedArray> CalculateLineEnds(Handle<String> src,
329  bool with_last_line) {
330  src = FlattenGetString(src);
331  // Rough estimate of line count based on a roughly estimated average
332  // length of (unpacked) code.
333  int line_count_estimate = src->length() >> 4;
334  List<int> line_ends(line_count_estimate);
335  Isolate* isolate = src->GetIsolate();
336  {
337  DisallowHeapAllocation no_allocation; // ensure vectors stay valid.
338  // Dispatch on type of strings.
339  String::FlatContent content = src->GetFlatContent();
340  ASSERT(content.IsFlat());
341  if (content.IsAscii()) {
342  CalculateLineEnds(isolate,
343  &line_ends,
344  content.ToOneByteVector(),
345  with_last_line);
346  } else {
347  CalculateLineEnds(isolate,
348  &line_ends,
349  content.ToUC16Vector(),
350  with_last_line);
351  }
352  }
353  int line_count = line_ends.length();
354  Handle<FixedArray> array = isolate->factory()->NewFixedArray(line_count);
355  for (int i = 0; i < line_count; i++) {
356  array->set(i, Smi::FromInt(line_ends[i]));
357  }
358  return array;
359 }
360 
361 
362 // Convert code position into line number.
363 int GetScriptLineNumber(Handle<Script> script, int code_pos) {
364  InitScriptLineEnds(script);
365  DisallowHeapAllocation no_allocation;
366  FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
367  const int line_ends_len = line_ends_array->length();
368 
369  if (!line_ends_len) return -1;
370 
371  if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) {
372  return script->line_offset()->value();
373  }
374 
375  int left = 0;
376  int right = line_ends_len;
377  while (int half = (right - left) / 2) {
378  if ((Smi::cast(line_ends_array->get(left + half)))->value() > code_pos) {
379  right -= half;
380  } else {
381  left += half;
382  }
383  }
384  return right + script->line_offset()->value();
385 }
386 
387 
388 // Convert code position into column number.
389 int GetScriptColumnNumber(Handle<Script> script, int code_pos) {
390  int line_number = GetScriptLineNumber(script, code_pos);
391  if (line_number == -1) return -1;
392 
393  DisallowHeapAllocation no_allocation;
394  FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
395  line_number = line_number - script->line_offset()->value();
396  if (line_number == 0) return code_pos + script->column_offset()->value();
397  int prev_line_end_pos =
398  Smi::cast(line_ends_array->get(line_number - 1))->value();
399  return code_pos - (prev_line_end_pos + 1);
400 }
401 
402 
403 int GetScriptLineNumberSafe(Handle<Script> script, int code_pos) {
404  DisallowHeapAllocation no_allocation;
405  if (!script->line_ends()->IsUndefined()) {
406  return GetScriptLineNumber(script, code_pos);
407  }
408  // Slow mode: we do not have line_ends. We have to iterate through source.
409  if (!script->source()->IsString()) {
410  return -1;
411  }
412  String* source = String::cast(script->source());
413  int line = 0;
414  int len = source->length();
415  for (int pos = 0; pos < len; pos++) {
416  if (pos == code_pos) {
417  break;
418  }
419  if (source->Get(pos) == '\n') {
420  line++;
421  }
422  }
423  return line;
424 }
425 
426 
427 // Compute the property keys from the interceptor.
428 // TODO(rossberg): support symbols in API, and filter here if needed.
430  Handle<JSObject> object) {
431  Isolate* isolate = receiver->GetIsolate();
432  Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
434  args(isolate, interceptor->data(), *receiver, *object);
435  v8::Handle<v8::Array> result;
436  if (!interceptor->enumerator()->IsUndefined()) {
438  v8::ToCData<v8::NamedPropertyEnumeratorCallback>(
439  interceptor->enumerator());
440  LOG(isolate, ApiObjectAccess("interceptor-named-enum", *object));
441  result = args.Call(enum_fun);
442  }
443 #if ENABLE_EXTRA_CHECKS
444  CHECK(result.IsEmpty() || v8::Utils::OpenHandle(*result)->IsJSObject());
445 #endif
446  return v8::Local<v8::Array>::New(reinterpret_cast<v8::Isolate*>(isolate),
447  result);
448 }
449 
450 
451 // Compute the element keys from the interceptor.
453  Handle<JSObject> object) {
454  Isolate* isolate = receiver->GetIsolate();
455  Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
457  args(isolate, interceptor->data(), *receiver, *object);
458  v8::Handle<v8::Array> result;
459  if (!interceptor->enumerator()->IsUndefined()) {
461  v8::ToCData<v8::IndexedPropertyEnumeratorCallback>(
462  interceptor->enumerator());
463  LOG(isolate, ApiObjectAccess("interceptor-indexed-enum", *object));
464  result = args.Call(enum_fun);
465 #if ENABLE_EXTRA_CHECKS
466  CHECK(result.IsEmpty() || v8::Utils::OpenHandle(*result)->IsJSObject());
467 #endif
468  }
469  return v8::Local<v8::Array>::New(reinterpret_cast<v8::Isolate*>(isolate),
470  result);
471 }
472 
473 
475  Isolate* isolate = script->GetIsolate();
476  Handle<String> name_or_source_url_key =
477  isolate->factory()->InternalizeOneByteString(
478  STATIC_ASCII_VECTOR("nameOrSourceURL"));
479  Handle<JSValue> script_wrapper = GetScriptWrapper(script);
480  Handle<Object> property = GetProperty(isolate,
481  script_wrapper,
482  name_or_source_url_key);
483  ASSERT(property->IsJSFunction());
484  Handle<JSFunction> method = Handle<JSFunction>::cast(property);
485  bool caught_exception;
486  Handle<Object> result = Execution::TryCall(method, script_wrapper, 0,
487  NULL, &caught_exception);
488  if (caught_exception) {
489  result = isolate->factory()->undefined_value();
490  }
491  return result;
492 }
493 
494 
495 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
496  int len = array->length();
497  for (int i = 0; i < len; i++) {
498  Object* e = array->get(i);
499  if (!(e->IsString() || e->IsNumber())) return false;
500  }
501  return true;
502 }
503 
504 
506  KeyCollectionType type,
507  bool* threw) {
508  USE(ContainsOnlyValidKeys);
509  Isolate* isolate = object->GetIsolate();
510  Handle<FixedArray> content = isolate->factory()->empty_fixed_array();
511  Handle<JSObject> arguments_boilerplate = Handle<JSObject>(
512  isolate->context()->native_context()->sloppy_arguments_boilerplate(),
513  isolate);
514  Handle<JSFunction> arguments_function = Handle<JSFunction>(
515  JSFunction::cast(arguments_boilerplate->map()->constructor()),
516  isolate);
517 
518  // Only collect keys if access is permitted.
519  for (Handle<Object> p = object;
520  *p != isolate->heap()->null_value();
521  p = Handle<Object>(p->GetPrototype(isolate), isolate)) {
522  if (p->IsJSProxy()) {
523  Handle<JSProxy> proxy(JSProxy::cast(*p), isolate);
524  Handle<Object> args[] = { proxy };
525  Handle<Object> names = Execution::Call(isolate,
526  isolate->proxy_enumerate(),
527  object,
528  ARRAY_SIZE(args),
529  args,
530  threw);
531  if (*threw) return content;
532  content = AddKeysFromJSArray(content, Handle<JSArray>::cast(names));
533  break;
534  }
535 
536  Handle<JSObject> current(JSObject::cast(*p), isolate);
537 
538  // Check access rights if required.
539  if (current->IsAccessCheckNeeded() &&
540  !isolate->MayNamedAccessWrapper(current,
541  isolate->factory()->undefined_value(),
542  v8::ACCESS_KEYS)) {
544  if (isolate->has_scheduled_exception()) {
545  isolate->PromoteScheduledException();
546  *threw = true;
547  }
548  break;
549  }
550 
551  // Compute the element keys.
552  Handle<FixedArray> element_keys =
553  isolate->factory()->NewFixedArray(current->NumberOfEnumElements());
554  current->GetEnumElementKeys(*element_keys);
555  content = UnionOfKeys(content, element_keys);
556  ASSERT(ContainsOnlyValidKeys(content));
557 
558  // Add the element keys from the interceptor.
559  if (current->HasIndexedInterceptor()) {
560  v8::Handle<v8::Array> result =
561  GetKeysForIndexedInterceptor(object, current);
562  if (!result.IsEmpty())
563  content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
564  ASSERT(ContainsOnlyValidKeys(content));
565  }
566 
567  // We can cache the computed property keys if access checks are
568  // not needed and no interceptors are involved.
569  //
570  // We do not use the cache if the object has elements and
571  // therefore it does not make sense to cache the property names
572  // for arguments objects. Arguments objects will always have
573  // elements.
574  // Wrapped strings have elements, but don't have an elements
575  // array or dictionary. So the fast inline test for whether to
576  // use the cache says yes, so we should not create a cache.
577  bool cache_enum_keys =
578  ((current->map()->constructor() != *arguments_function) &&
579  !current->IsJSValue() &&
580  !current->IsAccessCheckNeeded() &&
581  !current->HasNamedInterceptor() &&
582  !current->HasIndexedInterceptor());
583  // Compute the property keys and cache them if possible.
584  content =
585  UnionOfKeys(content, GetEnumPropertyKeys(current, cache_enum_keys));
586  ASSERT(ContainsOnlyValidKeys(content));
587 
588  // Add the property keys from the interceptor.
589  if (current->HasNamedInterceptor()) {
590  v8::Handle<v8::Array> result =
591  GetKeysForNamedInterceptor(object, current);
592  if (!result.IsEmpty())
593  content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
594  ASSERT(ContainsOnlyValidKeys(content));
595  }
596 
597  // If we only want local properties we bail out after the first
598  // iteration.
599  if (type == LOCAL_ONLY)
600  break;
601  }
602  return content;
603 }
604 
605 
607  Isolate* isolate = object->GetIsolate();
608  isolate->counters()->for_in()->Increment();
609  Handle<FixedArray> elements =
610  GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, threw);
611  return isolate->factory()->NewJSArrayWithElements(elements);
612 }
613 
614 
616  ASSERT(array->length() >= length);
617  if (array->length() == length) return array;
618 
619  Handle<FixedArray> new_array =
620  array->GetIsolate()->factory()->NewFixedArray(length);
621  for (int i = 0; i < length; ++i) new_array->set(i, array->get(i));
622  return new_array;
623 }
624 
625 
627  bool cache_result) {
628  Isolate* isolate = object->GetIsolate();
629  if (object->HasFastProperties()) {
630  if (object->map()->instance_descriptors()->HasEnumCache()) {
631  int own_property_count = object->map()->EnumLength();
632  // If we have an enum cache, but the enum length of the given map is set
633  // to kInvalidEnumCache, this means that the map itself has never used the
634  // present enum cache. The first step to using the cache is to set the
635  // enum length of the map by counting the number of own descriptors that
636  // are not DONT_ENUM or SYMBOLIC.
637  if (own_property_count == kInvalidEnumCacheSentinel) {
638  own_property_count = object->map()->NumberOfDescribedProperties(
640 
641  if (cache_result) object->map()->SetEnumLength(own_property_count);
642  }
643 
644  DescriptorArray* desc = object->map()->instance_descriptors();
645  Handle<FixedArray> keys(desc->GetEnumCache(), isolate);
646 
647  // In case the number of properties required in the enum are actually
648  // present, we can reuse the enum cache. Otherwise, this means that the
649  // enum cache was generated for a previous (smaller) version of the
650  // Descriptor Array. In that case we regenerate the enum cache.
651  if (own_property_count <= keys->length()) {
652  isolate->counters()->enum_cache_hits()->Increment();
653  return ReduceFixedArrayTo(keys, own_property_count);
654  }
655  }
656 
657  Handle<Map> map(object->map());
658 
659  if (map->instance_descriptors()->IsEmpty()) {
660  isolate->counters()->enum_cache_hits()->Increment();
661  if (cache_result) map->SetEnumLength(0);
662  return isolate->factory()->empty_fixed_array();
663  }
664 
665  isolate->counters()->enum_cache_misses()->Increment();
666  int num_enum = map->NumberOfDescribedProperties(ALL_DESCRIPTORS, DONT_SHOW);
667 
668  Handle<FixedArray> storage = isolate->factory()->NewFixedArray(num_enum);
669  Handle<FixedArray> indices = isolate->factory()->NewFixedArray(num_enum);
670 
672  Handle<DescriptorArray>(object->map()->instance_descriptors(), isolate);
673 
674  int real_size = map->NumberOfOwnDescriptors();
675  int enum_size = 0;
676  int index = 0;
677 
678  for (int i = 0; i < descs->number_of_descriptors(); i++) {
679  PropertyDetails details = descs->GetDetails(i);
680  Object* key = descs->GetKey(i);
681  if (!(details.IsDontEnum() || key->IsSymbol())) {
682  if (i < real_size) ++enum_size;
683  storage->set(index, key);
684  if (!indices.is_null()) {
685  if (details.type() != FIELD) {
686  indices = Handle<FixedArray>();
687  } else {
688  int field_index = descs->GetFieldIndex(i);
689  if (field_index >= map->inobject_properties()) {
690  field_index = -(field_index - map->inobject_properties() + 1);
691  }
692  indices->set(index, Smi::FromInt(field_index));
693  }
694  }
695  index++;
696  }
697  }
698  ASSERT(index == storage->length());
699 
700  Handle<FixedArray> bridge_storage =
701  isolate->factory()->NewFixedArray(
703  DescriptorArray* desc = object->map()->instance_descriptors();
704  desc->SetEnumCache(*bridge_storage,
705  *storage,
706  indices.is_null() ? Object::cast(Smi::FromInt(0))
707  : Object::cast(*indices));
708  if (cache_result) {
709  object->map()->SetEnumLength(enum_size);
710  }
711 
712  return ReduceFixedArrayTo(storage, enum_size);
713  } else {
714  Handle<NameDictionary> dictionary(object->property_dictionary());
715  int length = dictionary->NumberOfEnumElements();
716  if (length == 0) {
717  return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
718  }
719  Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length);
720  dictionary->CopyEnumKeysTo(*storage);
721  return storage;
722  }
723 }
724 
725 
727  : impl_(isolate->handle_scope_implementer()) {
728  impl_->BeginDeferredScope();
729  HandleScopeData* data = impl_->isolate()->handle_scope_data();
730  Object** new_next = impl_->GetSpareOrNewBlock();
731  Object** new_limit = &new_next[kHandleBlockSize];
732  ASSERT(data->limit == &impl_->blocks()->last()[kHandleBlockSize]);
733  impl_->blocks()->Add(new_next);
734 
735 #ifdef DEBUG
736  prev_level_ = data->level;
737 #endif
738  data->level++;
739  prev_limit_ = data->limit;
740  prev_next_ = data->next;
741  data->next = new_next;
742  data->limit = new_limit;
743 }
744 
745 
747  impl_->isolate()->handle_scope_data()->level--;
748  ASSERT(handles_detached_);
749  ASSERT(impl_->isolate()->handle_scope_data()->level == prev_level_);
750 }
751 
752 
754  DeferredHandles* deferred = impl_->Detach(prev_limit_);
755  HandleScopeData* data = impl_->isolate()->handle_scope_data();
756  data->next = prev_next_;
757  data->limit = prev_limit_;
758 #ifdef DEBUG
759  handles_detached_ = true;
760 #endif
761  return deferred;
762 }
763 
764 
766  Handle<Object> object,
767  Handle<Code> code) {
772  heap->AddWeakObjectToCodeDependency(*object, *dep));
773 }
774 
775 
776 } } // namespace v8::internal
byte * Address
Definition: globals.h:186
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter NULL
Definition: flags.cc:269
void SetEnumCache(FixedArray *bridge_storage, FixedArray *new_cache, Object *new_index_cache)
Definition: objects.cc:7945
static V8_INLINE Local< T > New(Isolate *isolate, Handle< T > that)
Definition: v8.h:5713
static void Destroy(Object **location)
void FlattenString(Handle< String > string)
Definition: handles.cc:151
internal::Object ** GetSpareOrNewBlock()
Definition: api.h:656
Handle< JSObject > NewJSObject(Handle< JSFunction > constructor, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:1319
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print statistics of the maximum memory committed for the heap in only print modified registers Don t break for ASM_UNIMPLEMENTED_BREAK macros print stack trace when an illegal exception is thrown randomize hashes to avoid predictable hash Fixed seed to use to hash property keys(0 means random)" "(with snapshots this option cannot override the baked-in seed)") DEFINE_bool(profile_deserialization
static Handle< Object > TryCall(Handle< JSFunction > func, Handle< Object > receiver, int argc, Handle< Object > argv[], bool *caught_exception)
Definition: execution.cc:199
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf map
Definition: flags.cc:350
static String * cast(Object *obj)
Handle< FixedArray > AddKeysFromJSArray(Handle< FixedArray > content, Handle< JSArray > array)
Definition: handles.cc:127
HandleScopeImplementer * handle_scope_implementer()
Definition: isolate.h:902
Isolate * isolate()
Definition: heap-inl.h:624
void ReportFailedAccessCheckWrapper(Handle< JSObject > receiver, v8::AccessType type)
Definition: isolate.h:752
static Smi * FromInt(int value)
Definition: objects-inl.h:1209
v8::Handle< v8::Array > GetKeysForIndexedInterceptor(Handle< JSReceiver > receiver, Handle< JSObject > object)
Definition: handles.cc:452
#define LOG(isolate, Call)
Definition: log.h:86
static Handle< T > cast(Handle< S > that)
Definition: handles.h:75
internal::Object ** limit
Definition: handles.h:321
static const int kEnumCacheBridgeLength
Definition: objects.h:3493
MaybeObject * AddWeakObjectToCodeDependency(Object *obj, DependentCode *dep)
Definition: heap.cc:6856
kSerializedDataOffset Object
Definition: objects-inl.h:5016
Handle< JSArray > NewJSArrayWithElements(Handle< FixedArrayBase > elements, ElementsKind elements_kind, int length, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:1456
Handle< Object > DeleteProperty(Handle< JSObject > object, Handle< Object > key)
Definition: handles.cc:170
void DeleteExtensions(internal::Object **prev_limit)
Definition: api.h:665
HandleScopeData * handle_scope_data()
Definition: isolate.h:900
Handle< FixedArray > UnionOfKeys(Handle< FixedArray > first, Handle< FixedArray > second)
Definition: handles.cc:134
void InitScriptLineEnds(Handle< Script > script)
Definition: handles.cc:278
#define ASSERT(condition)
Definition: checks.h:329
Handle< JSArray > GetKeysFor(Handle< JSReceiver > object, bool *threw)
Definition: handles.cc:606
static Script * cast(Object *obj)
#define CALL_HEAP_FUNCTION_VOID(ISOLATE, FUNCTION_CALL)
Definition: heap-inl.h:686
#define CHECK(condition)
Definition: checks.h:75
int GetScriptColumnNumber(Handle< Script > script, int code_pos)
Definition: handles.cc:389
Handle< Object > GetProperty(Handle< JSReceiver > obj, const char *name)
Definition: handles.cc:196
Factory * factory()
Definition: isolate.h:995
void(* IndexedPropertyEnumeratorCallback)(const PropertyCallbackInfo< Array > &info)
Definition: v8.h:3388
PropertyAttributes
static MUST_USE_RESULT MaybeObject * HasObjectProperty(Isolate *isolate, Handle< JSReceiver > object, Handle< Object > key)
Definition: runtime.cc:4964
bool MayNamedAccessWrapper(Handle< JSObject > receiver, Handle< Object > key, v8::AccessType type)
Definition: isolate.h:742
static Smi * cast(Object *object)
Handle< String > FlattenGetString(Handle< String > string)
Definition: handles.cc:156
Handle< Object > ForceDeleteProperty(Handle< JSObject > object, Handle< Object > key)
Definition: handles.cc:179
Handle< Object > HasProperty(Handle< JSReceiver > obj, Handle< Object > key)
Definition: handles.cc:189
DeferredHandleScope(Isolate *isolate)
Definition: handles.cc:726
void EnsureWeakObjectToCodeTable()
Definition: heap.cc:6880
static Handle< DependentCode > Insert(Handle< DependentCode > entries, DependencyGroup group, Handle< Object > object)
Definition: objects.cc:11540
static MUST_USE_RESULT MaybeObject * DeleteObjectProperty(Isolate *isolate, Handle< JSReceiver > object, Handle< Object > key, JSReceiver::DeleteMode mode)
Definition: runtime.cc:5442
Handle< FixedArray > ReduceFixedArrayTo(Handle< FixedArray > array, int length)
Definition: handles.cc:615
DeferredHandles * Detach()
Definition: handles.cc:753
V8_INLINE Isolate * GetIsolate() const
Definition: v8.h:449
static int NumberOfHandles(Isolate *isolate)
Definition: handles.cc:48
Context * native_context()
Definition: contexts.cc:67
Handle< Object > Create(Object *value)
#define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE)
Definition: heap-inl.h:679
static Handle< Object > ForceSetObjectProperty(Isolate *isolate, Handle< JSObject > object, Handle< Object > key, Handle< Object > value, PropertyAttributes attr)
Definition: runtime.cc:5387
GlobalHandles * global_handles()
Definition: isolate.h:918
Handle< JSValue > GetScriptWrapper(Handle< Script > script)
Definition: handles.cc:240
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
Vector< const uc16 > ToUC16Vector()
Definition: objects.h:8757
Handle< FixedArray > NewFixedArray(int size, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:53
int GetScriptLineNumberSafe(Handle< Script > script, int code_pos)
Definition: handles.cc:403
Handle< FixedArray > GetKeysInFixedArrayFor(Handle< JSReceiver > object, KeyCollectionType type, bool *threw)
Definition: handles.cc:505
#define STATIC_ASCII_VECTOR(x)
Definition: utils.h:570
static v8::internal::Handle< To > OpenHandle(v8::Local< From > handle)
Definition: api.h:308
V8_INLINE P * GetParameter() const
Definition: v8.h:451
internal::Object ** next
Definition: handles.h:320
static Address current_limit_address(Isolate *isolate)
Definition: handles.cc:122
void(* NamedPropertyEnumeratorCallback)(const PropertyCallbackInfo< Array > &info)
Definition: v8.h:3342
Context * context()
Definition: isolate.h:557
V8_INLINE bool IsString() const
Definition: v8.h:6265
List< internal::Object ** > * blocks()
Definition: api.h:557
void AddWeakObjectToCodeDependency(Heap *heap, Handle< Object > object, Handle< Code > code)
Definition: handles.cc:765
int GetScriptLineNumber(Handle< Script > script, int code_pos)
Definition: handles.cc:363
Failure * PromoteScheduledException()
Definition: isolate.cc:985
Handle< String > InternalizeOneByteString(Vector< const uint8_t > str)
Definition: factory.cc:232
v8::Handle< v8::Array > GetKeysForNamedInterceptor(Handle< JSReceiver > receiver, Handle< JSObject > object)
Definition: handles.cc:429
static Handle< Object > Call(Isolate *isolate, Handle< Object > callable, Handle< Object > receiver, int argc, Handle< Object > argv[], bool *pending_exception, bool convert_receiver=false)
Definition: execution.cc:153
bool is_null() const
Definition: handles.h:81
Handle< T > handle(T *t, Isolate *isolate)
Definition: handles.h:103
V8_INLINE bool IsEmpty() const
Definition: v8.h:248
bool IsNumber() const
Definition: api.cc:2416
Handle< String > LookupSingleCharacterStringFromCode(Isolate *isolate, uint32_t index)
Definition: handles.cc:212
static Object * cast(Object *value)
Definition: objects.h:1641
static void MakeWeak(Object **location, void *parameter, WeakCallback weak_callback)
Handle< String > InternalizeUtf8String(Vector< const char > str)
Definition: factory.cc:218
static JSValue * cast(Object *obj)
Definition: objects-inl.h:5758
Handle< Object > GetScriptNameOrSourceURL(Handle< Script > script)
Definition: handles.cc:474
Handle< JSGlobalProxy > ReinitializeJSGlobalProxy(Handle< JSFunction > constructor, Handle< JSGlobalProxy > global)
Definition: handles.cc:141
const int kHandleBlockSize
Definition: api.h:616
static MUST_USE_RESULT MaybeObject * GetObjectProperty(Isolate *isolate, Handle< Object > object, Handle< Object > key)
Definition: runtime.cc:4990
#define ASSERT_EQ(v1, v2)
Definition: checks.h:330
MUST_USE_RESULT MaybeObject * LookupSingleCharacterStringFromCode(uint16_t code)
Definition: heap.cc:3962
static JSProxy * cast(Object *obj)
void USE(T)
Definition: globals.h:341
Counters * counters()
Definition: isolate.h:859
Isolate * isolate() const
Definition: api.h:558
static FixedArray * cast(Object *obj)
FixedArray * GetEnumCache()
Definition: objects.h:3361
static bool ApiCheck(bool condition, const char *location, const char *message)
Definition: api.h:199
Object * get(int index)
Definition: objects-inl.h:2127
HeapObject * obj
bool has_scheduled_exception()
Definition: isolate.h:631
Handle< Object > ForceSetProperty(Handle< JSObject > object, Handle< Object > key, Handle< Object > value, PropertyAttributes attributes)
Definition: handles.cc:161
Handle< FixedArray > GetEnumPropertyKeys(Handle< JSObject > object, bool cache_result)
Definition: handles.cc:626
Vector< const uint8_t > ToOneByteVector()
Definition: objects.h:8751
enable upcoming ES6 features enable harmony block scoping enable harmony enable harmony proxies enable harmony generators enable harmony numeric enable harmony string enable harmony math functions harmony_scoping harmony_symbols harmony_collections harmony_iteration harmony_strings harmony_scoping harmony_maths tracks arrays with only smi values Optimize object Array DOM strings and string pretenure call new trace pretenuring decisions of HAllocate instructions track fields with only smi values track fields with heap values track_fields track_fields Enables optimizations which favor memory size over execution speed use string slices optimization filter maximum number of GVN fix point iterations use function inlining use allocation folding eliminate write barriers targeting allocations in optimized code maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining crankshaft harvests type feedback from stub cache trace check elimination phase hydrogen tracing filter trace hydrogen to given file name trace inlining decisions trace store elimination trace all use positions trace global value numbering trace hydrogen escape analysis trace the tracking of allocation sites trace map generalization environment for every instruction deoptimize every n garbage collections put a break point before deoptimizing deoptimize uncommon cases use on stack replacement trace array bounds check elimination perform array index dehoisting use load elimination use store elimination use constant folding eliminate unreachable code number of stress runs when picking a function to watch for shared function not JSFunction itself flushes the cache of optimized code for closures on every GC functions with arguments object maximum number of escape analysis fix point iterations allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms concurrent on stack replacement do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes number of stack frames inspected by the profiler percentage of ICs that must have type info to allow optimization extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long expose natives in global object expose freeBuffer extension expose gc extension under the specified name expose externalize string extension number of stack frames to capture disable builtin natives files print name of functions for which code is generated use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations always try to OSR functions trace optimize function deoptimization minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions trace debugging JSON request response trace out of bounds accesses to external arrays trace_js_array_abuse automatically set the debug break flag when debugger commands are in the queue abort by crashing maximum length of function source code printed in a stack trace max size of the new max size of the old max size of executable always perform global GCs print one trace line following each garbage collection do not print trace line after scavenger collection print statistics of the maximum memory committed for the heap in name
Definition: flags.cc:505
#define ARRAY_SIZE(a)
Definition: globals.h:333
static Address current_next_address(Isolate *isolate)
Definition: handles.cc:117
static JSObject * cast(Object *obj)
static Address current_level_address(Isolate *isolate)
Definition: handles.cc:112
const Address kHandleZapValue
Definition: v8globals.h:83
static void DeleteExtensions(Isolate *isolate)
Definition: handles.cc:96
DependentCode * LookupWeakObjectToCodeDependency(Object *obj)
Definition: heap.cc:6873
static JSFunction * cast(Object *obj)