15 char* HeapStringAllocator::allocate(
unsigned bytes) {
16 space_ = NewArray<char>(bytes);
21 bool StringStream::Put(
char c) {
22 if (full())
return false;
23 DCHECK(length_ < capacity_);
27 if (length_ == capacity_ - 2) {
28 unsigned new_capacity = capacity_;
29 char* new_buffer = allocator_->grow(&new_capacity);
30 if (new_capacity > capacity_) {
31 capacity_ = new_capacity;
36 length_ = capacity_ - 1;
37 buffer_[length_ - 4] =
'.';
38 buffer_[length_ - 3] =
'.';
39 buffer_[length_ - 2] =
'.';
40 buffer_[length_ - 1] =
'\n';
41 buffer_[length_] =
'\0';
46 buffer_[length_ + 1] =
'\0';
56 case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
57 case '6':
case '7':
case '8':
case '9':
case '.':
case '-':
65 void StringStream::Add(Vector<const char> format, Vector<FmtElm> elms) {
70 while (offset < format.length()) {
71 if (format[offset] !=
'%' || elm == elms.length()) {
77 EmbeddedVector<char, 24> temp;
78 int format_length = 0;
81 temp[format_length++] = format[offset++];
82 while (offset < format.length() &&
IsControlChar(format[offset]))
83 temp[format_length++] = format[offset++];
84 if (offset >= format.length())
86 char type = format[offset];
87 temp[format_length++] = type;
88 temp[format_length] =
'\0';
90 FmtElm current = elms[elm++];
94 const char* value = current.data_.u_c_str_;
100 Vector<const uc16> value = *current.data_.u_lc_str_;
101 for (
int i = 0;
i < value.length();
i++)
102 Put(
static_cast<char>(value[
i]));
107 Object* obj = current.data_.u_obj_;
113 int value = current.data_.u_int_;
114 if (0x20 <= value && value <= 0x7F) {
116 }
else if (value <= 0xff) {
117 Add(
"\\x%02x", value);
119 Add(
"\\u%04x", value);
123 case 'i':
case 'd':
case 'u':
case 'x':
case 'c':
case 'X': {
124 int value = current.data_.u_int_;
125 EmbeddedVector<char, 24> formatted;
126 int length =
SNPrintF(formatted, temp.start(), value);
127 Add(Vector<const char>(formatted.start(), length));
130 case 'f':
case 'g':
case 'G':
case 'e':
case 'E': {
131 double value = current.data_.u_double_;
135 }
else if (inf == 1) {
137 }
else if (std::isnan(value)) {
140 EmbeddedVector<char, 28> formatted;
141 SNPrintF(formatted, temp.start(), value);
142 Add(formatted.start());
147 void* value = current.data_.u_pointer_;
148 EmbeddedVector<char, 20> formatted;
149 SNPrintF(formatted, temp.start(), value);
150 Add(formatted.start());
160 DCHECK(buffer_[length_] ==
'\0');
164 void StringStream::PrintObject(
Object* o) {
170 }
else if (o->IsNumber() || o->IsOddball()) {
173 if (o->IsHeapObject()) {
174 HeapObject* ho = HeapObject::cast(o);
176 string_stream_debug_object_cache();
177 for (
int i = 0;
i < debug_object_cache->length();
i++) {
178 if ((*debug_object_cache)[
i] == o) {
184 Add(
"#%d#", debug_object_cache->length());
185 debug_object_cache->Add(HeapObject::cast(o));
193 void StringStream::Add(
const char* format) {
198 void StringStream::Add(Vector<const char> format) {
203 void StringStream::Add(
const char* format, FmtElm arg0) {
205 FmtElm argv[argc] = { arg0 };
206 Add(
CStrVector(format), Vector<FmtElm>(argv, argc));
210 void StringStream::Add(
const char* format, FmtElm arg0, FmtElm arg1) {
212 FmtElm argv[argc] = { arg0, arg1 };
213 Add(
CStrVector(format), Vector<FmtElm>(argv, argc));
217 void StringStream::Add(
const char* format, FmtElm arg0, FmtElm arg1,
220 FmtElm argv[argc] = { arg0, arg1, arg2 };
221 Add(
CStrVector(format), Vector<FmtElm>(argv, argc));
225 void StringStream::Add(
const char* format, FmtElm arg0, FmtElm arg1,
226 FmtElm arg2, FmtElm arg3) {
228 FmtElm argv[argc] = { arg0, arg1, arg2, arg3 };
229 Add(
CStrVector(format), Vector<FmtElm>(argv, argc));
233 void StringStream::Add(
const char* format, FmtElm arg0, FmtElm arg1,
234 FmtElm arg2, FmtElm arg3, FmtElm arg4) {
236 FmtElm argv[argc] = { arg0, arg1, arg2, arg3, arg4 };
237 Add(
CStrVector(format), Vector<FmtElm>(argv, argc));
241 SmartArrayPointer<const char> StringStream::ToCString()
const {
242 char* str = NewArray<char>(length_ + 1);
243 MemCopy(str, buffer_, length_);
245 return SmartArrayPointer<const char>(str);
249 void StringStream::Log(Isolate* isolate) {
250 LOG(isolate, StringEvent(
"StackDump", buffer_));
254 void StringStream::OutputToFile(FILE* out) {
259 unsigned position = 0;
260 for (
unsigned next; (next = position + 2048) < length_; position = next) {
261 char save = buffer_[next];
262 buffer_[next] =
'\0';
264 buffer_[next] = save;
270 Handle<String> StringStream::ToString(Isolate* isolate) {
271 return isolate->factory()->NewStringFromUtf8(
272 Vector<const char>(buffer_, length_)).ToHandleChecked();
276 void StringStream::ClearMentionedObjectCache(Isolate* isolate) {
277 isolate->set_string_stream_current_security_token(
NULL);
278 if (isolate->string_stream_debug_object_cache() ==
NULL) {
281 isolate->string_stream_debug_object_cache()->Clear();
286 bool StringStream::IsMentionedObjectCacheClear(Isolate* isolate) {
287 return isolate->string_stream_debug_object_cache()->length() == 0;
292 bool StringStream::Put(String* str) {
293 return Put(str, 0, str->length());
297 bool StringStream::Put(String* str,
int start,
int end) {
298 ConsStringIteratorOp op;
299 StringCharacterStream stream(str, &op, start);
300 for (
int i = start;
i < end && stream.HasMore();
i++) {
302 if (c >= 127 || c < 32) {
305 if (!Put(
static_cast<char>(c))) {
314 if (
name->IsString()) {
315 String* str = String::cast(
name);
316 if (str->length() > 0) {
319 Add(
"/* anonymous */");
327 void StringStream::PrintUsingMap(JSObject* js_object) {
328 Map*
map = js_object->map();
329 if (!js_object->GetHeap()->Contains(
map) ||
330 !
map->IsHeapObject() ||
332 Add(
"<Invalid map>\n");
335 int real_size =
map->NumberOfOwnDescriptors();
336 DescriptorArray* descs =
map->instance_descriptors();
337 for (
int i = 0;
i < real_size;
i++) {
338 PropertyDetails details = descs->GetDetails(
i);
339 if (details.type() ==
FIELD) {
340 Object* key = descs->GetKey(
i);
341 if (key->IsString() || key->IsNumber()) {
343 if (key->IsString()) {
344 len = String::cast(key)->length();
346 for (; len < 18; len++)
348 if (key->IsString()) {
349 Put(String::cast(key));
354 FieldIndex index = FieldIndex::ForDescriptor(
map,
i);
355 Object* value = js_object->RawFastPropertyAt(index);
363 void StringStream::PrintFixedArray(FixedArray* array,
unsigned int limit) {
364 Heap* heap = array->GetHeap();
365 for (
unsigned int i = 0;
i < 10 &&
i < limit;
i++) {
366 Object* element = array->get(
i);
367 if (element != heap->the_hole_value()) {
368 for (
int len = 1; len < 18; len++)
370 Add(
"%d: %o\n",
i, array->get(
i));
379 void StringStream::PrintByteArray(
ByteArray* byte_array) {
380 unsigned int limit = byte_array->length();
381 for (
unsigned int i = 0;
i < 10 &&
i < limit;
i++) {
382 byte b = byte_array->get(
i);
383 Add(
" %d: %3d 0x%02x",
i, b, b);
384 if (b >=
' ' && b <=
'~') {
386 }
else if (b ==
'\n') {
388 }
else if (b ==
'\r') {
390 }
else if (b >= 1 && b <= 26) {
391 Add(
" ^%c", b +
'A' - 1);
401 void StringStream::PrintMentionedObjectCache(Isolate* isolate) {
403 isolate->string_stream_debug_object_cache();
404 Add(
"==== Key ============================================\n\n");
405 for (
int i = 0;
i < debug_object_cache->length();
i++) {
406 HeapObject* printee = (*debug_object_cache)[
i];
407 Add(
" #%d# %p: ",
i, printee);
408 printee->ShortPrint(
this);
410 if (printee->IsJSObject()) {
411 if (printee->IsJSValue()) {
412 Add(
" value(): %o\n", JSValue::cast(printee)->value());
414 PrintUsingMap(JSObject::cast(printee));
415 if (printee->IsJSArray()) {
416 JSArray* array = JSArray::cast(printee);
417 if (array->HasFastObjectElements()) {
418 unsigned int limit = FixedArray::cast(array->elements())->length();
419 unsigned int length =
420 static_cast<uint32_t>(JSArray::cast(array)->length()->Number());
421 if (length < limit) limit = length;
422 PrintFixedArray(FixedArray::cast(array->elements()), limit);
425 }
else if (printee->IsByteArray()) {
426 PrintByteArray(ByteArray::cast(printee));
427 }
else if (printee->IsFixedArray()) {
428 unsigned int limit = FixedArray::cast(printee)->length();
429 PrintFixedArray(FixedArray::cast(printee), limit);
435 void StringStream::PrintSecurityTokenIfChanged(
Object* f) {
436 if (!f->IsHeapObject())
return;
437 HeapObject* obj = HeapObject::cast(f);
438 Isolate* isolate = obj->GetIsolate();
439 Heap* heap = isolate->heap();
440 if (!heap->Contains(obj))
return;
441 Map*
map = obj->map();
442 if (!
map->IsHeapObject() ||
443 !heap->Contains(
map) ||
445 !f->IsJSFunction()) {
449 JSFunction* fun = JSFunction::cast(f);
450 Object* perhaps_context = fun->context();
451 if (perhaps_context->IsHeapObject() &&
452 heap->Contains(HeapObject::cast(perhaps_context)) &&
453 perhaps_context->IsContext()) {
454 Context* context = fun->context();
455 if (!heap->Contains(context)) {
456 Add(
"(Function context is outside heap)\n");
459 Object* token = context->native_context()->security_token();
460 if (token != isolate->string_stream_current_security_token()) {
461 Add(
"Security context: %o\n", token);
462 isolate->set_string_stream_current_security_token(token);
465 Add(
"(Function context is corrupt)\n");
470 void StringStream::PrintFunction(
Object* f,
Object* receiver, Code** code) {
471 if (!f->IsHeapObject()) {
472 Add(
"/* warning: 'function' was not a heap object */ ");
475 Heap* heap = HeapObject::cast(f)->GetHeap();
476 if (!heap->Contains(HeapObject::cast(f))) {
477 Add(
"/* warning: 'function' was not on the heap */ ");
480 if (!heap->Contains(HeapObject::cast(f)->map())) {
481 Add(
"/* warning: function's map was not on the heap */ ");
484 if (!HeapObject::cast(f)->
map()->IsMap()) {
485 Add(
"/* warning: function's map was not a valid map */ ");
488 if (f->IsJSFunction()) {
489 JSFunction* fun = JSFunction::cast(f);
491 PrintPrototype(fun, receiver);
493 }
else if (f->IsInternalizedString()) {
497 Add(
"/* unresolved */ ");
503 Add(
"/* warning: no JSFunction object or function name found */ ");
508 void StringStream::PrintPrototype(JSFunction* fun,
Object* receiver) {
510 bool print_name =
false;
511 Isolate* isolate = fun->GetIsolate();
512 for (PrototypeIterator iter(isolate, receiver,
514 !iter.IsAtEnd(); iter.Advance()) {
515 if (iter.GetCurrent()->IsJSObject()) {
516 Object* key = JSObject::cast(iter.GetCurrent())->SlowReverseLookup(fun);
517 if (key != isolate->heap()->undefined_value()) {
518 if (!
name->IsString() ||
520 !String::cast(
name)->Equals(String::cast(key))) {
523 if (
name->IsString() && String::cast(
name)->length() == 0) {
537 PrintName(fun->shared()->name());
543 char* HeapStringAllocator::grow(
unsigned* bytes) {
544 unsigned new_bytes = *bytes * 2;
546 if (new_bytes <= *bytes) {
549 char* new_space = NewArray<char>(new_bytes);
550 if (new_space ==
NULL) {
553 MemCopy(new_space, space_, *bytes);
static const int kMaxShortPrintLength
static Vector< T > empty()
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf map
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS 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 enable alignment of csp to bytes on platforms which prefer the register to always be expose gc extension under the specified name show built in functions in stack traces use random jit cookie to mask large constants minimum length for automatic enable preparsing CPU profiler sampling interval in microseconds trace out of bounds accesses to external arrays default size of stack region v8 is allowed to maximum length of function source code printed in a stack trace min size of a semi the new space consists of two semi spaces print one trace line following each garbage collection do not print trace line after scavenger collection print cumulative GC statistics in name
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS 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 enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define LOG(isolate, Call)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
Vector< const char > CStrVector(const char *data)
void DeleteArray(T *array)
static const int kMentionedObjectCacheMaxSize
int SNPrintF(Vector< char > str, const char *format,...)
kSerializedDataOffset Object
static bool IsControlChar(char c)
void PrintF(const char *format,...)
List< HeapObject * > DebugObjectCache
void MemCopy(void *dest, const void *src, size_t size)
Debugger support for the V8 JavaScript engine.