v8  3.14.5(node0.10.28)
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 
49  Isolate* isolate = Isolate::Current();
51  int n = impl->blocks()->length();
52  if (n == 0) return 0;
53  return ((n - 1) * kHandleBlockSize) + static_cast<int>(
54  (isolate->handle_scope_data()->next - impl->blocks()->last()));
55 }
56 
57 
58 Object** HandleScope::Extend() {
59  Isolate* isolate = Isolate::Current();
61  isolate->handle_scope_data();
62 
63  Object** result = current->next;
64 
65  ASSERT(result == current->limit);
66  // Make sure there's at least one scope on the stack and that the
67  // top of the scope stack isn't a barrier.
68  if (current->level == 0) {
69  Utils::ReportApiFailure("v8::HandleScope::CreateHandle()",
70  "Cannot create a handle without a HandleScope");
71  return NULL;
72  }
73  HandleScopeImplementer* impl = isolate->handle_scope_implementer();
74  // If there's more room in the last block, we use that. This is used
75  // for fast creation of scopes after scope barriers.
76  if (!impl->blocks()->is_empty()) {
77  Object** limit = &impl->blocks()->last()[kHandleBlockSize];
78  if (current->limit != limit) {
79  current->limit = limit;
80  ASSERT(limit - current->next < kHandleBlockSize);
81  }
82  }
83 
84  // If we still haven't found a slot for the handle, we extend the
85  // current handle scope by allocating a new handle block.
86  if (result == current->limit) {
87  // If there's a spare block, use it for growing the current scope.
88  result = impl->GetSpareOrNewBlock();
89  // Add the extension to the global list of blocks, but count the
90  // extension as part of the current scope.
91  impl->blocks()->Add(result);
92  current->limit = &result[kHandleBlockSize];
93  }
94 
95  return result;
96 }
97 
98 
100  ASSERT(isolate == Isolate::Current());
102  isolate->handle_scope_data();
103  isolate->handle_scope_implementer()->DeleteExtensions(current->limit);
104 }
105 
106 
107 void HandleScope::ZapRange(Object** start, Object** end) {
108  ASSERT(end - start <= kHandleBlockSize);
109  for (Object** p = start; p != end; p++) {
110  *reinterpret_cast<Address*>(p) = v8::internal::kHandleZapValue;
111  }
112 }
113 
114 
116  return reinterpret_cast<Address>(
117  &Isolate::Current()->handle_scope_data()->level);
118 }
119 
120 
122  return reinterpret_cast<Address>(
123  &Isolate::Current()->handle_scope_data()->next);
124 }
125 
126 
128  return reinterpret_cast<Address>(
129  &Isolate::Current()->handle_scope_data()->limit);
130 }
131 
132 
134  Handle<JSArray> array) {
135  CALL_HEAP_FUNCTION(content->GetIsolate(),
136  content->AddKeysFromJSArray(*array), FixedArray);
137 }
138 
139 
141  Handle<FixedArray> second) {
142  CALL_HEAP_FUNCTION(first->GetIsolate(),
143  first->UnionOfKeys(*second), FixedArray);
144 }
145 
146 
148  Handle<JSFunction> constructor,
149  Handle<JSGlobalProxy> global) {
151  constructor->GetIsolate(),
152  constructor->GetHeap()->ReinitializeJSGlobalProxy(*constructor, *global),
153  JSGlobalProxy);
154 }
155 
156 
158  // If objects constructed from this function exist then changing
159  // 'estimated_nof_properties' is dangerous since the previous value might
160  // have been compiled into the fast construct stub. More over, the inobject
161  // slack tracking logic might have adjusted the previous value, so even
162  // passing the same value is risky.
163  if (func->shared()->live_objects_may_exist()) return;
164 
165  func->shared()->set_expected_nof_properties(nof);
166  if (func->has_initial_map()) {
167  Handle<Map> new_initial_map =
168  func->GetIsolate()->factory()->CopyMap(
169  Handle<Map>(func->initial_map()));
170  new_initial_map->set_unused_property_fields(nof);
171  func->set_initial_map(*new_initial_map);
172  }
173 }
174 
175 
177  CALL_HEAP_FUNCTION_VOID(func->GetIsolate(),
178  func->SetPrototype(*value));
179 }
180 
181 
182 static int ExpectedNofPropertiesFromEstimate(int estimate) {
183  // If no properties are added in the constructor, they are more likely
184  // to be added later.
185  if (estimate == 0) estimate = 2;
186 
187  // We do not shrink objects that go into a snapshot (yet), so we adjust
188  // the estimate conservatively.
189  if (Serializer::enabled()) return estimate + 2;
190 
191  // Inobject slack tracking will reclaim redundant inobject space later,
192  // so we can afford to adjust the estimate generously.
193  if (FLAG_clever_optimizations) {
194  return estimate + 8;
195  } else {
196  return estimate + 3;
197  }
198 }
199 
200 
202  int estimate) {
203  // See the comment in SetExpectedNofProperties.
204  if (shared->live_objects_may_exist()) return;
205 
206  shared->set_expected_nof_properties(
207  ExpectedNofPropertiesFromEstimate(estimate));
208 }
209 
210 
212  CALL_HEAP_FUNCTION_VOID(string->GetIsolate(), string->TryFlatten());
213 }
214 
215 
217  CALL_HEAP_FUNCTION(string->GetIsolate(), string->TryFlatten(), String);
218 }
219 
220 
222  Handle<Object> prototype) {
223  ASSERT(function->should_have_prototype());
224  CALL_HEAP_FUNCTION(function->GetIsolate(),
226  *prototype,
227  NULL),
228  Object);
229 }
230 
231 
233  Handle<Object> key,
234  Handle<Object> value,
235  PropertyAttributes attributes,
236  StrictModeFlag strict_mode) {
237  Isolate* isolate = Isolate::Current();
239  isolate,
241  isolate, object, key, value, attributes, strict_mode),
242  Object);
243 }
244 
245 
247  Handle<Object> key,
248  Handle<Object> value,
249  PropertyAttributes attributes) {
250  Isolate* isolate = object->GetIsolate();
252  isolate,
254  isolate, object, key, value, attributes),
255  Object);
256 }
257 
258 
260  Handle<Object> key) {
261  Isolate* isolate = object->GetIsolate();
262  CALL_HEAP_FUNCTION(isolate,
263  Runtime::ForceDeleteObjectProperty(isolate, object, key),
264  Object);
265 }
266 
267 
269  Handle<String> key,
270  Handle<Object> value,
271  PropertyAttributes attributes,
272  StrictModeFlag strict_mode) {
273  CALL_HEAP_FUNCTION(object->GetIsolate(),
274  object->SetPropertyWithInterceptor(*key,
275  *value,
276  attributes,
277  strict_mode),
278  Object);
279 }
280 
281 
283  const char* name) {
284  Isolate* isolate = obj->GetIsolate();
285  Handle<String> str = isolate->factory()->LookupAsciiSymbol(name);
286  CALL_HEAP_FUNCTION(isolate, obj->GetProperty(*str), Object);
287 }
288 
289 
291  Handle<Object> key) {
292  Isolate* isolate = Isolate::Current();
293  CALL_HEAP_FUNCTION(isolate,
294  Runtime::GetObjectProperty(isolate, obj, key), Object);
295 }
296 
297 
299  Handle<JSObject> holder,
300  Handle<String> name,
301  PropertyAttributes* attributes) {
302  Isolate* isolate = receiver->GetIsolate();
303  CALL_HEAP_FUNCTION(isolate,
304  holder->GetPropertyWithInterceptor(*receiver,
305  *name,
306  attributes),
307  Object);
308 }
309 
310 
312  const bool skip_hidden_prototypes = false;
313  CALL_HEAP_FUNCTION(obj->GetIsolate(),
314  obj->SetPrototype(*value, skip_hidden_prototypes), Object);
315 }
316 
317 
319  Isolate* isolate = Isolate::Current();
321  isolate,
322  isolate->heap()->LookupSingleCharacterStringFromCode(index), Object);
323 }
324 
325 
327  int start,
328  int end,
329  PretenureFlag pretenure) {
330  CALL_HEAP_FUNCTION(str->GetIsolate(),
331  str->SubString(start, end, pretenure), String);
332 }
333 
334 
336  Isolate* isolate = obj->GetIsolate();
337  CALL_HEAP_FUNCTION(isolate,
338  isolate->heap()->CopyJSObject(*obj), JSObject);
339 }
340 
341 
343  CALL_HEAP_FUNCTION(obj->GetIsolate(), obj->DefineAccessor(*info), Object);
344 }
345 
346 
347 // Wrappers for scripts are kept alive and cached in weak global
348 // handles referred from foreign objects held by the scripts as long as
349 // they are used. When they are not used anymore, the garbage
350 // collector will call the weak callback on the global handle
351 // associated with the wrapper and get rid of both the wrapper and the
352 // handle.
353 static void ClearWrapperCache(Persistent<v8::Value> handle, void*) {
354  Handle<Object> cache = Utils::OpenHandle(*handle);
355  JSValue* wrapper = JSValue::cast(*cache);
356  Foreign* foreign = Script::cast(wrapper->value())->wrapper();
357  ASSERT(foreign->foreign_address() ==
358  reinterpret_cast<Address>(cache.location()));
359  foreign->set_foreign_address(0);
360  Isolate* isolate = Isolate::Current();
361  isolate->global_handles()->Destroy(cache.location());
362  isolate->counters()->script_wrappers()->Decrement();
363 }
364 
365 
367  if (script->wrapper()->foreign_address() != NULL) {
368  // Return the script wrapper directly from the cache.
369  return Handle<JSValue>(
370  reinterpret_cast<JSValue**>(script->wrapper()->foreign_address()));
371  }
372  Isolate* isolate = Isolate::Current();
373  // Construct a new script wrapper.
374  isolate->counters()->script_wrappers()->Increment();
375  Handle<JSFunction> constructor = isolate->script_function();
376  Handle<JSValue> result =
377  Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
378  result->set_value(*script);
379 
380  // Create a new weak global handle and use it to cache the wrapper
381  // for future use. The cache will automatically be cleared by the
382  // garbage collector when it is not used anymore.
383  Handle<Object> handle = isolate->global_handles()->Create(*result);
384  isolate->global_handles()->MakeWeak(handle.location(), NULL,
385  &ClearWrapperCache);
386  script->wrapper()->set_foreign_address(
387  reinterpret_cast<Address>(handle.location()));
388  return result;
389 }
390 
391 
392 // Init line_ends array with code positions of line ends inside script
393 // source.
395  if (!script->line_ends()->IsUndefined()) return;
396 
397  Isolate* isolate = script->GetIsolate();
398 
399  if (!script->source()->IsString()) {
400  ASSERT(script->source()->IsUndefined());
401  Handle<FixedArray> empty = isolate->factory()->NewFixedArray(0);
402  script->set_line_ends(*empty);
403  ASSERT(script->line_ends()->IsFixedArray());
404  return;
405  }
406 
407  Handle<String> src(String::cast(script->source()), isolate);
408 
409  Handle<FixedArray> array = CalculateLineEnds(src, true);
410 
411  if (*array != isolate->heap()->empty_fixed_array()) {
412  array->set_map(isolate->heap()->fixed_cow_array_map());
413  }
414 
415  script->set_line_ends(*array);
416  ASSERT(script->line_ends()->IsFixedArray());
417 }
418 
419 
420 template <typename SourceChar>
421 static void CalculateLineEnds(Isolate* isolate,
422  List<int>* line_ends,
423  Vector<const SourceChar> src,
424  bool with_last_line) {
425  const int src_len = src.length();
426  StringSearch<char, SourceChar> search(isolate, CStrVector("\n"));
427 
428  // Find and record line ends.
429  int position = 0;
430  while (position != -1 && position < src_len) {
431  position = search.Search(src, position);
432  if (position != -1) {
433  line_ends->Add(position);
434  position++;
435  } else if (with_last_line) {
436  // Even if the last line misses a line end, it is counted.
437  line_ends->Add(src_len);
438  return;
439  }
440  }
441 }
442 
443 
444 Handle<FixedArray> CalculateLineEnds(Handle<String> src,
445  bool with_last_line) {
446  src = FlattenGetString(src);
447  // Rough estimate of line count based on a roughly estimated average
448  // length of (unpacked) code.
449  int line_count_estimate = src->length() >> 4;
450  List<int> line_ends(line_count_estimate);
451  Isolate* isolate = src->GetIsolate();
452  {
453  AssertNoAllocation no_heap_allocation; // ensure vectors stay valid.
454  // Dispatch on type of strings.
455  String::FlatContent content = src->GetFlatContent();
456  ASSERT(content.IsFlat());
457  if (content.IsAscii()) {
458  CalculateLineEnds(isolate,
459  &line_ends,
460  content.ToAsciiVector(),
461  with_last_line);
462  } else {
463  CalculateLineEnds(isolate,
464  &line_ends,
465  content.ToUC16Vector(),
466  with_last_line);
467  }
468  }
469  int line_count = line_ends.length();
470  Handle<FixedArray> array = isolate->factory()->NewFixedArray(line_count);
471  for (int i = 0; i < line_count; i++) {
472  array->set(i, Smi::FromInt(line_ends[i]));
473  }
474  return array;
475 }
476 
477 
478 // Convert code position into line number.
479 int GetScriptLineNumber(Handle<Script> script, int code_pos) {
480  InitScriptLineEnds(script);
481  AssertNoAllocation no_allocation;
482  FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
483  const int line_ends_len = line_ends_array->length();
484 
485  if (!line_ends_len) return -1;
486 
487  if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) {
488  return script->line_offset()->value();
489  }
490 
491  int left = 0;
492  int right = line_ends_len;
493  while (int half = (right - left) / 2) {
494  if ((Smi::cast(line_ends_array->get(left + half)))->value() > code_pos) {
495  right -= half;
496  } else {
497  left += half;
498  }
499  }
500  return right + script->line_offset()->value();
501 }
502 
503 // Convert code position into column number.
504 int GetScriptColumnNumber(Handle<Script> script, int code_pos) {
505  int line_number = GetScriptLineNumber(script, code_pos);
506  if (line_number == -1) return -1;
507 
508  AssertNoAllocation no_allocation;
509  FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
510  line_number = line_number - script->line_offset()->value();
511  if (line_number == 0) return code_pos + script->column_offset()->value();
512  int prev_line_end_pos =
513  Smi::cast(line_ends_array->get(line_number - 1))->value();
514  return code_pos - (prev_line_end_pos + 1);
515 }
516 
517 int GetScriptLineNumberSafe(Handle<Script> script, int code_pos) {
518  AssertNoAllocation no_allocation;
519  if (!script->line_ends()->IsUndefined()) {
520  return GetScriptLineNumber(script, code_pos);
521  }
522  // Slow mode: we do not have line_ends. We have to iterate through source.
523  if (!script->source()->IsString()) {
524  return -1;
525  }
526  String* source = String::cast(script->source());
527  int line = 0;
528  int len = source->length();
529  for (int pos = 0; pos < len; pos++) {
530  if (pos == code_pos) {
531  break;
532  }
533  if (source->Get(pos) == '\n') {
534  line++;
535  }
536  }
537  return line;
538 }
539 
540 
541 void CustomArguments::IterateInstance(ObjectVisitor* v) {
542  v->VisitPointers(values_, values_ + ARRAY_SIZE(values_));
543 }
544 
545 
546 // Compute the property keys from the interceptor.
548  Handle<JSObject> object) {
549  Isolate* isolate = receiver->GetIsolate();
550  Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
551  CustomArguments args(isolate, interceptor->data(), *receiver, *object);
552  v8::AccessorInfo info(args.end());
553  v8::Handle<v8::Array> result;
554  if (!interceptor->enumerator()->IsUndefined()) {
555  v8::NamedPropertyEnumerator enum_fun =
556  v8::ToCData<v8::NamedPropertyEnumerator>(interceptor->enumerator());
557  LOG(isolate, ApiObjectAccess("interceptor-named-enum", *object));
558  {
559  // Leaving JavaScript.
560  VMState state(isolate, EXTERNAL);
561  result = enum_fun(info);
562  }
563  }
564 #if ENABLE_EXTRA_CHECKS
565  CHECK(result.IsEmpty() || v8::Utils::OpenHandle(*result)->IsJSObject());
566 #endif
567  return result;
568 }
569 
570 
571 // Compute the element keys from the interceptor.
573  Handle<JSObject> object) {
574  Isolate* isolate = receiver->GetIsolate();
575  Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
576  CustomArguments args(isolate, interceptor->data(), *receiver, *object);
577  v8::AccessorInfo info(args.end());
578  v8::Handle<v8::Array> result;
579  if (!interceptor->enumerator()->IsUndefined()) {
581  v8::ToCData<v8::IndexedPropertyEnumerator>(interceptor->enumerator());
582  LOG(isolate, ApiObjectAccess("interceptor-indexed-enum", *object));
583  {
584  // Leaving JavaScript.
585  VMState state(isolate, EXTERNAL);
586  result = enum_fun(info);
587 #if ENABLE_EXTRA_CHECKS
588  CHECK(result.IsEmpty() || v8::Utils::OpenHandle(*result)->IsJSObject());
589 #endif
590  }
591  }
592  return result;
593 }
594 
595 
596 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
597  int len = array->length();
598  for (int i = 0; i < len; i++) {
599  Object* e = array->get(i);
600  if (!(e->IsString() || e->IsNumber())) return false;
601  }
602  return true;
603 }
604 
605 
607  KeyCollectionType type,
608  bool* threw) {
609  USE(ContainsOnlyValidKeys);
610  Isolate* isolate = object->GetIsolate();
611  Handle<FixedArray> content = isolate->factory()->empty_fixed_array();
612  Handle<JSObject> arguments_boilerplate = Handle<JSObject>(
613  isolate->context()->native_context()->arguments_boilerplate(),
614  isolate);
615  Handle<JSFunction> arguments_function = Handle<JSFunction>(
616  JSFunction::cast(arguments_boilerplate->map()->constructor()),
617  isolate);
618 
619  // Only collect keys if access is permitted.
620  for (Handle<Object> p = object;
621  *p != isolate->heap()->null_value();
622  p = Handle<Object>(p->GetPrototype(), isolate)) {
623  if (p->IsJSProxy()) {
624  Handle<JSProxy> proxy(JSProxy::cast(*p), isolate);
625  Handle<Object> args[] = { proxy };
627  isolate->proxy_enumerate(), object, ARRAY_SIZE(args), args, threw);
628  if (*threw) return content;
629  content = AddKeysFromJSArray(content, Handle<JSArray>::cast(names));
630  break;
631  }
632 
633  Handle<JSObject> current(JSObject::cast(*p), isolate);
634 
635  // Check access rights if required.
636  if (current->IsAccessCheckNeeded() &&
637  !isolate->MayNamedAccess(*current,
638  isolate->heap()->undefined_value(),
639  v8::ACCESS_KEYS)) {
640  isolate->ReportFailedAccessCheck(*current, v8::ACCESS_KEYS);
641  break;
642  }
643 
644  // Compute the element keys.
645  Handle<FixedArray> element_keys =
646  isolate->factory()->NewFixedArray(current->NumberOfEnumElements());
647  current->GetEnumElementKeys(*element_keys);
648  content = UnionOfKeys(content, element_keys);
649  ASSERT(ContainsOnlyValidKeys(content));
650 
651  // Add the element keys from the interceptor.
652  if (current->HasIndexedInterceptor()) {
653  v8::Handle<v8::Array> result =
654  GetKeysForIndexedInterceptor(object, current);
655  if (!result.IsEmpty())
656  content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
657  ASSERT(ContainsOnlyValidKeys(content));
658  }
659 
660  // We can cache the computed property keys if access checks are
661  // not needed and no interceptors are involved.
662  //
663  // We do not use the cache if the object has elements and
664  // therefore it does not make sense to cache the property names
665  // for arguments objects. Arguments objects will always have
666  // elements.
667  // Wrapped strings have elements, but don't have an elements
668  // array or dictionary. So the fast inline test for whether to
669  // use the cache says yes, so we should not create a cache.
670  bool cache_enum_keys =
671  ((current->map()->constructor() != *arguments_function) &&
672  !current->IsJSValue() &&
673  !current->IsAccessCheckNeeded() &&
674  !current->HasNamedInterceptor() &&
675  !current->HasIndexedInterceptor());
676  // Compute the property keys and cache them if possible.
677  content =
678  UnionOfKeys(content, GetEnumPropertyKeys(current, cache_enum_keys));
679  ASSERT(ContainsOnlyValidKeys(content));
680 
681  // Add the property keys from the interceptor.
682  if (current->HasNamedInterceptor()) {
683  v8::Handle<v8::Array> result =
684  GetKeysForNamedInterceptor(object, current);
685  if (!result.IsEmpty())
686  content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
687  ASSERT(ContainsOnlyValidKeys(content));
688  }
689 
690  // If we only want local properties we bail out after the first
691  // iteration.
692  if (type == LOCAL_ONLY)
693  break;
694  }
695  return content;
696 }
697 
698 
700  Isolate* isolate = object->GetIsolate();
701  isolate->counters()->for_in()->Increment();
702  Handle<FixedArray> elements =
703  GetKeysInFixedArrayFor(object, INCLUDE_PROTOS, threw);
704  return isolate->factory()->NewJSArrayWithElements(elements);
705 }
706 
707 
709  ASSERT(array->length() >= length);
710  if (array->length() == length) return array;
711 
712  Handle<FixedArray> new_array =
713  array->GetIsolate()->factory()->NewFixedArray(length);
714  for (int i = 0; i < length; ++i) new_array->set(i, array->get(i));
715  return new_array;
716 }
717 
718 
720  bool cache_result) {
721  Isolate* isolate = object->GetIsolate();
722  if (object->HasFastProperties()) {
723  if (object->map()->instance_descriptors()->HasEnumCache()) {
724  int own_property_count = object->map()->EnumLength();
725  // If we have an enum cache, but the enum length of the given map is set
726  // to kInvalidEnumCache, this means that the map itself has never used the
727  // present enum cache. The first step to using the cache is to set the
728  // enum length of the map by counting the number of own descriptors that
729  // are not DONT_ENUM.
730  if (own_property_count == Map::kInvalidEnumCache) {
731  own_property_count = object->map()->NumberOfDescribedProperties(
733 
734  if (cache_result) object->map()->SetEnumLength(own_property_count);
735  }
736 
737  DescriptorArray* desc = object->map()->instance_descriptors();
738  Handle<FixedArray> keys(desc->GetEnumCache(), isolate);
739 
740  // In case the number of properties required in the enum are actually
741  // present, we can reuse the enum cache. Otherwise, this means that the
742  // enum cache was generated for a previous (smaller) version of the
743  // Descriptor Array. In that case we regenerate the enum cache.
744  if (own_property_count <= keys->length()) {
745  isolate->counters()->enum_cache_hits()->Increment();
746  return ReduceFixedArrayTo(keys, own_property_count);
747  }
748  }
749 
750  Handle<Map> map(object->map());
751 
752  if (map->instance_descriptors()->IsEmpty()) {
753  isolate->counters()->enum_cache_hits()->Increment();
754  if (cache_result) map->SetEnumLength(0);
755  return isolate->factory()->empty_fixed_array();
756  }
757 
758  isolate->counters()->enum_cache_misses()->Increment();
759  int num_enum = map->NumberOfDescribedProperties(ALL_DESCRIPTORS, DONT_ENUM);
760 
761  Handle<FixedArray> storage = isolate->factory()->NewFixedArray(num_enum);
762  Handle<FixedArray> indices = isolate->factory()->NewFixedArray(num_enum);
763 
765  Handle<DescriptorArray>(object->map()->instance_descriptors(), isolate);
766 
767  int real_size = map->NumberOfOwnDescriptors();
768  int enum_size = 0;
769  int index = 0;
770 
771  for (int i = 0; i < descs->number_of_descriptors(); i++) {
772  PropertyDetails details = descs->GetDetails(i);
773  if (!details.IsDontEnum()) {
774  if (i < real_size) ++enum_size;
775  storage->set(index, descs->GetKey(i));
776  if (!indices.is_null()) {
777  if (details.type() != FIELD) {
778  indices = Handle<FixedArray>();
779  } else {
780  int field_index = Descriptor::IndexFromValue(descs->GetValue(i));
781  if (field_index >= map->inobject_properties()) {
782  field_index = -(field_index - map->inobject_properties() + 1);
783  }
784  indices->set(index, Smi::FromInt(field_index));
785  }
786  }
787  index++;
788  }
789  }
790  ASSERT(index == storage->length());
791 
792  Handle<FixedArray> bridge_storage =
793  isolate->factory()->NewFixedArray(
795  DescriptorArray* desc = object->map()->instance_descriptors();
796  desc->SetEnumCache(*bridge_storage,
797  *storage,
798  indices.is_null() ? Object::cast(Smi::FromInt(0))
799  : Object::cast(*indices));
800  if (cache_result) {
801  object->map()->SetEnumLength(enum_size);
802  }
803 
804  return ReduceFixedArrayTo(storage, enum_size);
805  } else {
806  Handle<StringDictionary> dictionary(object->property_dictionary());
807 
808  int length = dictionary->NumberOfElements();
809  if (length == 0) {
810  return Handle<FixedArray>(isolate->heap()->empty_fixed_array());
811  }
812 
813  // The enumeration array is generated by allocating an array big enough to
814  // hold all properties that have been seen, whether they are are deleted or
815  // not. Subsequently all visible properties are added to the array. If some
816  // properties were not visible, the array is trimmed so it only contains
817  // visible properties. This improves over adding elements and sorting by
818  // index by having linear complexity rather than n*log(n).
819 
820  // By comparing the monotonous NextEnumerationIndex to the NumberOfElements,
821  // we can predict the number of holes in the final array. If there will be
822  // more than 50% holes, regenerate the enumeration indices to reduce the
823  // number of holes to a minimum. This avoids allocating a large array if
824  // many properties were added but subsequently deleted.
825  int next_enumeration = dictionary->NextEnumerationIndex();
826  if (!object->IsGlobalObject() && next_enumeration > (length * 3) / 2) {
828  next_enumeration = dictionary->NextEnumerationIndex();
829  }
830 
831  Handle<FixedArray> storage =
832  isolate->factory()->NewFixedArray(next_enumeration);
833 
834  storage = Handle<FixedArray>(dictionary->CopyEnumKeysTo(*storage));
835  ASSERT(storage->length() == object->NumberOfLocalProperties(DONT_ENUM));
836  return storage;
837  }
838 }
839 
840 
842  Handle<Object> key) {
843  CALL_HEAP_FUNCTION(table->GetIsolate(),
844  table->Add(*key),
845  ObjectHashSet);
846 }
847 
848 
850  Handle<Object> key) {
851  CALL_HEAP_FUNCTION(table->GetIsolate(),
852  table->Remove(*key),
853  ObjectHashSet);
854 }
855 
856 
858  Handle<Object> key,
859  Handle<Object> value) {
860  CALL_HEAP_FUNCTION(table->GetIsolate(),
861  table->Put(*key, *value),
863 }
864 
865 
866 // This method determines the type of string involved and then gets the UTF8
867 // length of the string. It doesn't flatten the string and has log(n) recursion
868 // for a string of length n. If the failure flag gets set, then we have to
869 // flatten the string and retry. Failures are caused by surrogate pairs in deep
870 // cons strings.
871 
872 // Single surrogate characters that are encountered in the UTF-16 character
873 // sequence of the input string get counted as 3 UTF-8 bytes, because that
874 // is the way that WriteUtf8 will encode them. Surrogate pairs are counted and
875 // encoded as one 4-byte UTF-8 sequence.
876 
877 // This function conceptually uses recursion on the two halves of cons strings.
878 // However, in order to avoid the recursion going too deep it recurses on the
879 // second string of the cons, but iterates on the first substring (by manually
880 // eliminating it as a tail recursion). This means it counts the UTF-8 length
881 // from the end to the start, which makes no difference to the total.
882 
883 // Surrogate pairs are recognized even if they are split across two sides of a
884 // cons, which complicates the implementation somewhat. Therefore, too deep
885 // recursion cannot always be avoided. This case is detected, and the failure
886 // flag is set, a signal to the caller that the string should be flattened and
887 // the operation retried.
889  int from,
890  int to,
891  bool followed_by_surrogate,
892  int max_recursion,
893  bool* failure,
894  bool* starts_with_surrogate) {
895  if (from == to) return 0;
896  int total = 0;
897  bool dummy;
898  while (true) {
899  if (input->IsAsciiRepresentation()) {
900  *starts_with_surrogate = false;
901  return total + to - from;
902  }
903  switch (StringShape(input).representation_tag()) {
904  case kConsStringTag: {
905  ConsString* str = ConsString::cast(input);
906  String* first = str->first();
907  String* second = str->second();
908  int first_length = first->length();
909  if (first_length - from > to - first_length) {
910  if (first_length < to) {
911  // Right hand side is shorter. No need to check the recursion depth
912  // since this can only happen log(n) times.
913  bool right_starts_with_surrogate = false;
914  total += Utf8LengthHelper(second,
915  0,
916  to - first_length,
917  followed_by_surrogate,
918  max_recursion - 1,
919  failure,
920  &right_starts_with_surrogate);
921  if (*failure) return 0;
922  followed_by_surrogate = right_starts_with_surrogate;
923  input = first;
924  to = first_length;
925  } else {
926  // We only need the left hand side.
927  input = first;
928  }
929  } else {
930  if (first_length > from) {
931  // Left hand side is shorter.
932  if (first->IsAsciiRepresentation()) {
933  total += first_length - from;
934  *starts_with_surrogate = false;
935  starts_with_surrogate = &dummy;
936  input = second;
937  from = 0;
938  to -= first_length;
939  } else if (second->IsAsciiRepresentation()) {
940  followed_by_surrogate = false;
941  total += to - first_length;
942  input = first;
943  to = first_length;
944  } else if (max_recursion > 0) {
945  bool right_starts_with_surrogate = false;
946  // Recursing on the long one. This may fail.
947  total += Utf8LengthHelper(second,
948  0,
949  to - first_length,
950  followed_by_surrogate,
951  max_recursion - 1,
952  failure,
953  &right_starts_with_surrogate);
954  if (*failure) return 0;
955  input = first;
956  to = first_length;
957  followed_by_surrogate = right_starts_with_surrogate;
958  } else {
959  *failure = true;
960  return 0;
961  }
962  } else {
963  // We only need the right hand side.
964  input = second;
965  from = 0;
966  to -= first_length;
967  }
968  }
969  continue;
970  }
971  case kExternalStringTag:
972  case kSeqStringTag: {
973  Vector<const uc16> vector = input->GetFlatContent().ToUC16Vector();
974  const uc16* p = vector.start();
976  for (int i = from; i < to; i++) {
977  uc16 c = p[i];
978  total += unibrow::Utf8::Length(c, previous);
979  previous = c;
980  }
981  if (to - from > 0) {
982  if (unibrow::Utf16::IsLeadSurrogate(previous) &&
983  followed_by_surrogate) {
985  }
986  if (unibrow::Utf16::IsTrailSurrogate(p[from])) {
987  *starts_with_surrogate = true;
988  }
989  }
990  return total;
991  }
992  case kSlicedStringTag: {
993  SlicedString* str = SlicedString::cast(input);
994  int offset = str->offset();
995  input = str->parent();
996  from += offset;
997  to += offset;
998  continue;
999  }
1000  default:
1001  break;
1002  }
1003  UNREACHABLE();
1004  return 0;
1005  }
1006  return 0;
1007 }
1008 
1009 
1011  bool dummy;
1012  bool failure;
1013  int len;
1014  const int kRecursionBudget = 100;
1015  do {
1016  failure = false;
1017  len = Utf8LengthHelper(
1018  *str, 0, str->length(), false, kRecursionBudget, &failure, &dummy);
1019  if (failure) FlattenString(str);
1020  } while (failure);
1021  return len;
1022 }
1023 
1024 
1026  : impl_(isolate->handle_scope_implementer()) {
1027  ASSERT(impl_->isolate() == Isolate::Current());
1028  impl_->BeginDeferredScope();
1030  impl_->isolate()->handle_scope_data();
1031  Object** new_next = impl_->GetSpareOrNewBlock();
1032  Object** new_limit = &new_next[kHandleBlockSize];
1033  ASSERT(data->limit == &impl_->blocks()->last()[kHandleBlockSize]);
1034  impl_->blocks()->Add(new_next);
1035 
1036 #ifdef DEBUG
1037  prev_level_ = data->level;
1038 #endif
1039  data->level++;
1040  prev_limit_ = data->limit;
1041  prev_next_ = data->next;
1042  data->next = new_next;
1043  data->limit = new_limit;
1044 }
1045 
1046 
1048  impl_->isolate()->handle_scope_data()->level--;
1049  ASSERT(handles_detached_);
1050  ASSERT(impl_->isolate()->handle_scope_data()->level == prev_level_);
1051 }
1052 
1053 
1055  DeferredHandles* deferred = impl_->Detach(prev_limit_);
1057  impl_->isolate()->handle_scope_data();
1058  data->next = prev_next_;
1059  data->limit = prev_limit_;
1060 #ifdef DEBUG
1061  handles_detached_ = true;
1062 #endif
1063  return deferred;
1064 }
1065 
1066 
1067 } } // namespace v8::internal
byte * Address
Definition: globals.h:157
int Utf8Length(Handle< String > str)
Definition: handles.cc:1010
void SetEnumCache(FixedArray *bridge_storage, FixedArray *new_cache, Object *new_index_cache)
Definition: objects.cc:6053
Handle< Array >(* NamedPropertyEnumerator)(const AccessorInfo &info)
Definition: v8.h:2086
void FlattenString(Handle< String > string)
Definition: handles.cc:211
static int NumberOfHandles()
Definition: handles.cc:48
internal::Object ** GetSpareOrNewBlock()
Definition: api.h:547
Handle< JSObject > NewJSObject(Handle< JSFunction > constructor, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:904
static Address current_level_address()
Definition: handles.cc:115
static void DoGenerateNewEnumerationIndices(Handle< StringDictionary > dictionary)
Definition: objects.cc:12427
static String * cast(Object *obj)
Handle< FixedArray > AddKeysFromJSArray(Handle< FixedArray > content, Handle< JSArray > array)
Definition: handles.cc:133
HandleScopeImplementer * handle_scope_implementer()
Definition: isolate.h:864
Handle< Object > SetPropertyWithInterceptor(Handle< JSObject > object, Handle< String > key, Handle< Object > value, PropertyAttributes attributes, StrictModeFlag strict_mode)
Definition: handles.cc:268
static Smi * FromInt(int value)
Definition: objects-inl.h:981
v8::Handle< v8::Array > GetKeysForIndexedInterceptor(Handle< JSReceiver > receiver, Handle< JSObject > object)
Definition: handles.cc:572
#define LOG(isolate, Call)
Definition: log.h:81
void ReportFailedAccessCheck(JSObject *receiver, v8::AccessType type)
Definition: isolate.cc:773
static MUST_USE_RESULT MaybeObject * ForceDeleteObjectProperty(Isolate *isolate, Handle< JSReceiver > object, Handle< Object > key)
Definition: runtime.cc:4357
static Handle< T > cast(Handle< S > that)
Definition: handles.h:81
bool MayNamedAccess(JSObject *receiver, Object *key, v8::AccessType type)
Definition: isolate.cc:828
bool IsAsciiRepresentation()
Definition: objects-inl.h:290
Vector< const char > ToAsciiVector()
Definition: objects.h:7139
static const int kEnumCacheBridgeLength
Definition: objects.h:2626
v8::HandleScope::Data HandleScopeData
Definition: apiutils.h:69
static bool enabled()
Definition: serialize.h:481
static MUST_USE_RESULT MaybeObject * SetObjectProperty(Isolate *isolate, Handle< Object > object, Handle< Object > key, Handle< Object > value, PropertyAttributes attr, StrictModeFlag strict_mode)
Definition: runtime.cc:4222
Handle< Object > SetAccessor(Handle< JSObject > obj, Handle< AccessorInfo > info)
Definition: handles.cc:342
void DeleteExtensions(internal::Object **prev_limit)
Definition: api.h:556
void SetPrototypeProperty(Handle< JSFunction > func, Handle< JSObject > value)
Definition: handles.cc:176
static Address current_next_address()
Definition: handles.cc:121
Handle< FixedArray > UnionOfKeys(Handle< FixedArray > first, Handle< FixedArray > second)
Definition: handles.cc:140
void InitScriptLineEnds(Handle< Script > script)
Definition: handles.cc:394
#define ASSERT(condition)
Definition: checks.h:270
Handle< JSArray > GetKeysFor(Handle< JSReceiver > object, bool *threw)
Definition: handles.cc:699
static Script * cast(Object *obj)
#define CALL_HEAP_FUNCTION_VOID(ISOLATE, FUNCTION_CALL)
Definition: heap-inl.h:565
#define CHECK(condition)
Definition: checks.h:56
Handle< Object > GetPropertyWithInterceptor(Handle< JSObject > receiver, Handle< JSObject > holder, Handle< String > name, PropertyAttributes *attributes)
Definition: handles.cc:298
int GetScriptColumnNumber(Handle< Script > script, int code_pos)
Definition: handles.cc:504
Handle< Object > GetProperty(Handle< JSReceiver > obj, const char *name)
Definition: handles.cc:282
MUST_USE_RESULT MaybeObject * CopyJSObject(JSObject *source)
Definition: heap.cc:4254
Factory * factory()
Definition: isolate.h:992
PropertyAttributes
Handle< String > LookupAsciiSymbol(Vector< const char > str)
Definition: factory.cc:174
static Smi * cast(Object *object)
Handle< String > FlattenGetString(Handle< String > string)
Definition: handles.cc:216
Handle< Object > ForceDeleteProperty(Handle< JSObject > object, Handle< Object > key)
Definition: handles.cc:259
static const int kInvalidEnumCache
Definition: objects.h:5121
static Address current_limit_address()
Definition: handles.cc:127
Handle< String > SubString(Handle< String > str, int start, int end, PretenureFlag pretenure)
Definition: handles.cc:326
DeferredHandleScope(Isolate *isolate)
Definition: handles.cc:1025
T ** location() const
Definition: handles.h:75
static uchar Length(uchar chr, int previous)
Definition: unicode-inl.h:124
Handle< FixedArray > ReduceFixedArrayTo(Handle< FixedArray > array, int length)
Definition: handles.cc:708
DeferredHandles * Detach()
Definition: handles.cc:1054
#define UNREACHABLE()
Definition: checks.h:50
T * start() const
Definition: utils.h:390
Handle< Object > LookupSingleCharacterStringFromCode(uint32_t index)
Definition: handles.cc:318
void SetExpectedNofProperties(Handle< JSFunction > func, int nof)
Definition: handles.cc:157
static SlicedString * cast(Object *obj)
int Utf8LengthHelper(String *input, int from, int to, bool followed_by_surrogate, int max_recursion, bool *failure, bool *starts_with_surrogate)
Definition: handles.cc:888
Context * native_context()
Definition: contexts.cc:58
Handle< Object > Create(Object *value)
#define CALL_HEAP_FUNCTION(ISOLATE, FUNCTION_CALL, TYPE)
Definition: heap-inl.h:558
Handle< ObjectHashSet > ObjectHashSetAdd(Handle< ObjectHashSet > table, Handle< Object > key)
Definition: handles.cc:841
Handle< Object > SetProperty(Handle< Object > object, Handle< Object > key, Handle< Object > value, PropertyAttributes attributes, StrictModeFlag strict_mode)
Definition: handles.cc:232
GlobalHandles * global_handles()
Definition: isolate.h:880
Handle< JSValue > GetScriptWrapper(Handle< Script > script)
Definition: handles.cc:366
Vector< const uc16 > ToUC16Vector()
Definition: objects.h:7145
Handle< FixedArray > NewFixedArray(int size, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:44
v8::ImplementationUtilities::HandleScopeData * handle_scope_data()
Definition: isolate.h:861
int GetScriptLineNumberSafe(Handle< Script > script, int code_pos)
Definition: handles.cc:517
Handle< FixedArray > GetKeysInFixedArrayFor(Handle< JSReceiver > object, KeyCollectionType type, bool *threw)
Definition: handles.cc:606
static Handle< Object > Call(Handle< Object > callable, Handle< Object > receiver, int argc, Handle< Object > argv[], bool *pending_exception, bool convert_receiver=false)
Definition: execution.cc:150
Vector< const char > CStrVector(const char *data)
Definition: utils.h:526
Handle< ObjectHashTable > PutIntoObjectHashTable(Handle< ObjectHashTable > table, Handle< Object > key, Handle< Object > value)
Definition: handles.cc:857
Handle< JSArray > NewJSArrayWithElements(Handle< FixedArrayBase > elements, ElementsKind elements_kind=TERMINAL_FAST_ELEMENTS_KIND, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:951
Context * context()
Definition: isolate.h:520
bool IsString() const
Definition: v8.h:4508
List< internal::Object ** > * blocks()
Definition: api.h:451
FlatContent GetFlatContent()
Definition: objects.cc:6191
int GetScriptLineNumber(Handle< Script > script, int code_pos)
Definition: handles.cc:479
static MUST_USE_RESULT MaybeObject * FunctionSetPrototype(JSObject *object, Object *value, void *)
Definition: accessors.cc:467
v8::Handle< v8::Array > GetKeysForNamedInterceptor(Handle< JSReceiver > receiver, Handle< JSObject > object)
Definition: handles.cc:547
bool is_null() const
Definition: handles.h:87
V8EXPORT bool IsNumber() const
Definition: api.cc:2183
static Object * cast(Object *value)
Definition: objects.h:1007
uint16_t uc16
Definition: globals.h:259
static JSValue * cast(Object *obj)
Definition: objects-inl.h:4600
static const unsigned kBytesSavedByCombiningSurrogates
Definition: unicode.h:171
Handle< JSGlobalProxy > ReinitializeJSGlobalProxy(Handle< JSFunction > constructor, Handle< JSGlobalProxy > global)
Definition: handles.cc:147
const int kHandleBlockSize
Definition: api.h:510
static MUST_USE_RESULT MaybeObject * GetObjectProperty(Isolate *isolate, Handle< Object > object, Handle< Object > key)
Definition: runtime.cc:3970
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit 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 SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available 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 MIPS FPU instructions if expose natives in global object expose gc extension number of stack frames to capture disable builtin natives files print a stack trace if an assertion failure occurs use random jit cookie to mask large constants trace lazy optimization use adaptive optimizations prepare for turning on always opt minimum length for automatic enable preparsing maximum number of optimization attempts before giving up cache prototype transitions automatically set the debug break flag when debugger commands are in the queue always cause a debug break before aborting 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 more details following each garbage collection print amount of external allocated memory after each time it is adjusted flush code that we expect not to use again before full gc do incremental marking steps track object counts and memory usage use caching Perform compaction on every full GC Never perform compaction on full GC testing only Compact code space on full incremental collections Default seed for initializing random allows verbose printing trace parsing and preparsing Check icache flushes in ARM and MIPS simulator Stack alingment in bytes in print stack trace when throwing exceptions 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(preemption
MUST_USE_RESULT MaybeObject * LookupSingleCharacterStringFromCode(uint16_t code)
Definition: heap.cc:3492
static MUST_USE_RESULT MaybeObject * ForceSetObjectProperty(Isolate *isolate, Handle< JSObject > object, Handle< Object > key, Handle< Object > value, PropertyAttributes attr)
Definition: runtime.cc:4304
static JSProxy * cast(Object *obj)
void IterateInstance(ObjectVisitor *v)
Definition: handles.cc:541
void USE(T)
Definition: globals.h:289
Counters * counters()
Definition: isolate.h:819
Isolate * isolate() const
Definition: api.h:452
static FixedArray * cast(Object *obj)
static bool ReportApiFailure(const char *location, const char *message)
Definition: api.cc:220
bool IsEmpty() const
Definition: v8.h:209
FixedArray * GetEnumCache()
Definition: objects.h:2528
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit 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 SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available 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 MIPS FPU instructions if NULL
Definition: flags.cc:301
Object * get(int index)
Definition: objects-inl.h:1737
static bool IsLeadSurrogate(int code)
Definition: unicode.h:120
Handle< Object > ForceSetProperty(Handle< JSObject > object, Handle< Object > key, Handle< Object > value, PropertyAttributes attributes)
Definition: handles.cc:246
Handle< ObjectHashSet > ObjectHashSetRemove(Handle< ObjectHashSet > table, Handle< Object > key)
Definition: handles.cc:849
void SetExpectedNofPropertiesFromEstimate(Handle< SharedFunctionInfo > shared, int estimate)
Definition: handles.cc:201
static bool IsTrailSurrogate(int code)
Definition: unicode.h:124
void MakeWeak(Object **location, void *parameter, WeakReferenceCallback callback)
Handle< Object > SetPrototype(Handle< JSFunction > function, Handle< Object > prototype)
Definition: handles.cc:221
Handle< FixedArray > GetEnumPropertyKeys(Handle< JSObject > object, bool cache_result)
Definition: handles.cc:719
static ConsString * cast(Object *obj)
Handle< Array >(* IndexedPropertyEnumerator)(const AccessorInfo &info)
Definition: v8.h:2125
#define ARRAY_SIZE(a)
Definition: globals.h:281
static JSObject * cast(Object *obj)
const Address kHandleZapValue
Definition: v8globals.h:81
static const int kNoPreviousCharacter
Definition: unicode.h:132
static void DeleteExtensions(Isolate *isolate)
Definition: handles.cc:99
Handle< JSObject > Copy(Handle< JSObject > obj)
Definition: handles.cc:335
static JSFunction * cast(Object *obj)