13fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "factory.h" 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "string-stream.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "allocation-inl.h" 343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kMentionedObjectCacheMaxSize = 256; 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* HeapStringAllocator::allocate(unsigned bytes) { 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block space_ = NewArray<char>(bytes); 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return space_; 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockNoAllocationStringAllocator::NoAllocationStringAllocator(char* memory, 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned size) { 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block size_ = size; 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block space_ = memory; 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StringStream::Put(char c) { 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (full()) return false; 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(length_ < capacity_); 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Since the trailing '\0' is not accounted for in length_ fullness is 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // indicated by a difference of 1 between length_ and capacity_. Thus when 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // reaching a difference of 2 we need to grow the buffer. 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (length_ == capacity_ - 2) { 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned new_capacity = capacity_; 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* new_buffer = allocator_->grow(&new_capacity); 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (new_capacity > capacity_) { 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block capacity_ = new_capacity; 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_ = new_buffer; 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Reached the end of the available buffer. 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(capacity_ >= 5); 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block length_ = capacity_ - 1; // Indicate fullness of the stream. 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[length_ - 4] = '.'; 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[length_ - 3] = '.'; 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[length_ - 2] = '.'; 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[length_ - 1] = '\n'; 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[length_] = '\0'; 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[length_] = c; 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[length_ + 1] = '\0'; 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block length_++; 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A control character is one that configures a format element. For 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// instance, in %.5s, .5 are control characters. 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic bool IsControlChar(char c) { 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (c) { 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '0': case '1': case '2': case '3': case '4': case '5': 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case '6': case '7': case '8': case '9': case '.': case '-': 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::Add(Vector<const char> format, Vector<FmtElm> elms) { 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If we already ran out of space then return immediately. 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (full()) return; 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int offset = 0; 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int elm = 0; 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (offset < format.length()) { 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (format[offset] != '%' || elm == elms.length()) { 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Put(format[offset]); 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block offset++; 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block continue; 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Read this formatting directive into a temporary buffer 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, 24> temp; 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int format_length = 0; 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Skip over the whole control character sequence until the 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // format element type 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block temp[format_length++] = format[offset++]; 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block while (offset < format.length() && IsControlChar(format[offset])) 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block temp[format_length++] = format[offset++]; 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (offset >= format.length()) 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char type = format[offset]; 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block temp[format_length++] = type; 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block temp[format_length] = '\0'; 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block offset++; 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FmtElm current = elms[elm++]; 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block switch (type) { 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 's': { 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT_EQ(FmtElm::C_STR, current.type_); 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char* value = current.data_.u_c_str_; 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(value); 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'w': { 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT_EQ(FmtElm::LC_STR, current.type_); 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Vector<const uc16> value = *current.data_.u_lc_str_; 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < value.length(); i++) 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Put(static_cast<char>(value[i])); 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'o': { 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT_EQ(FmtElm::OBJ, current.type_); 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* obj = current.data_.u_obj_; 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintObject(obj); 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'k': { 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT_EQ(FmtElm::INT, current.type_); 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int value = current.data_.u_int_; 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (0x20 <= value && value <= 0x7F) { 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Put(value); 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (value <= 0xff) { 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("\\x%02x", value); 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("\\u%04x", value); 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'i': case 'd': case 'u': case 'x': case 'c': case 'X': { 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int value = current.data_.u_int_; 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, 24> formatted; 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int length = OS::SNPrintF(formatted, temp.start(), value); 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(Vector<const char>(formatted.start(), length)); 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'f': case 'g': case 'G': case 'e': case 'E': { 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block double value = current.data_.u_double_; 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, 28> formatted; 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(formatted, temp.start(), value); 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(formatted.start()); 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block case 'p': { 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void* value = current.data_.u_pointer_; 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EmbeddedVector<char, 20> formatted; 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OS::SNPrintF(formatted, temp.start(), value); 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(formatted.start()); 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block default: 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNREACHABLE(); 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block break; 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Verify that the buffer is 0-terminated 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(buffer_[length_] == '\0'); 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::PrintObject(Object* o) { 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block o->ShortPrint(this); 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (o->IsString()) { 190d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (String::cast(o)->length() <= String::kMaxShortPrintLength) { 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (o->IsNumber() || o->IsOddball()) { 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (o->IsHeapObject()) { 19744f0eee88ff00398ff7f715fab053374d808c90dSteve Block DebugObjectCache* debug_object_cache = Isolate::Current()-> 19844f0eee88ff00398ff7f715fab053374d808c90dSteve Block string_stream_debug_object_cache(); 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < debug_object_cache->length(); i++) { 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if ((*debug_object_cache)[i] == o) { 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("#%d#", i); 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (debug_object_cache->length() < kMentionedObjectCacheMaxSize) { 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("#%d#", debug_object_cache->length()); 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block debug_object_cache->Add(HeapObject::cast(o)); 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("@%p", o); 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::Add(const char* format) { 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(CStrVector(format)); 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::Add(Vector<const char> format) { 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(format, Vector<FmtElm>::empty()); 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::Add(const char* format, FmtElm arg0) { 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char argc = 1; 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FmtElm argv[argc] = { arg0 }; 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(CStrVector(format), Vector<FmtElm>(argv, argc)); 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::Add(const char* format, FmtElm arg0, FmtElm arg1) { 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char argc = 2; 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FmtElm argv[argc] = { arg0, arg1 }; 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(CStrVector(format), Vector<FmtElm>(argv, argc)); 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::Add(const char* format, FmtElm arg0, FmtElm arg1, 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FmtElm arg2) { 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char argc = 3; 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FmtElm argv[argc] = { arg0, arg1, arg2 }; 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(CStrVector(format), Vector<FmtElm>(argv, argc)); 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::Add(const char* format, FmtElm arg0, FmtElm arg1, 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FmtElm arg2, FmtElm arg3) { 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const char argc = 4; 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FmtElm argv[argc] = { arg0, arg1, arg2, arg3 }; 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(CStrVector(format), Vector<FmtElm>(argv, argc)); 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 255589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSmartArrayPointer<const char> StringStream::ToCString() const { 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* str = NewArray<char>(length_ + 1); 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memcpy(str, buffer_, length_); 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block str[length_] = '\0'; 259589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch return SmartArrayPointer<const char>(str); 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::Log() { 26444f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOG(ISOLATE, StringEvent("StackDump", buffer_)); 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 268b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid StringStream::OutputToFile(FILE* out) { 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Dump the output to stdout, but make sure to break it up into 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // manageable chunks to avoid losing parts of the output in the OS 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // printing code. This is a problem on Windows in particular; see 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the VPrint() function implementations in platform-win32.cc. 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned position = 0; 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (unsigned next; (next = position + 2048) < length_; position = next) { 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char save = buffer_[next]; 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[next] = '\0'; 277b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch internal::PrintF(out, "%s", &buffer_[position]); 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block buffer_[next] = save; 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 280b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch internal::PrintF(out, "%s", &buffer_[position]); 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<String> StringStream::ToString() { 28544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return FACTORY->NewStringFromUtf8(Vector<const char>(buffer_, length_)); 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::ClearMentionedObjectCache() { 29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 29144f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->set_string_stream_current_security_token(NULL); 29244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (isolate->string_stream_debug_object_cache() == NULL) { 29344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->set_string_stream_debug_object_cache( 29444f0eee88ff00398ff7f715fab053374d808c90dSteve Block new List<HeapObject*, PreallocatedStorage>(0)); 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 29644f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->string_stream_debug_object_cache()->Clear(); 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StringStream::IsMentionedObjectCacheClear() { 30244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return ( 30344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->string_stream_debug_object_cache()->length() == 0); 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StringStream::Put(String* str) { 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Put(str, 0, str->length()); 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StringStream::Put(String* str, int start, int end) { 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StringInputBuffer name_buffer(str); 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name_buffer.Seek(start); 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = start; i < end && name_buffer.has_more(); i++) { 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int c = name_buffer.GetNext(); 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (c >= 127 || c < 32) { 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block c = '?'; 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!Put(c)) { 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return false; // Output was truncated. 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::PrintName(Object* name) { 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (name->IsString()) { 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* str = String::cast(name); 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (str->length() > 0) { 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Put(str); 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("/* anonymous */"); 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("%o", name); 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::PrintUsingMap(JSObject* js_object) { 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Map* map = js_object->map(); 34544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!HEAP->Contains(map) || 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !map->IsHeapObject() || 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !map->IsMap()) { 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("<Invalid map>\n"); 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DescriptorArray* descs = map->instance_descriptors(); 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < descs->number_of_descriptors(); i++) { 3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (descs->GetType(i) == FIELD) { 3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* key = descs->GetKey(i); 3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key->IsString() || key->IsNumber()) { 3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int len = 3; 3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key->IsString()) { 3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch len = String::cast(key)->length(); 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (; len < 18; len++) 3613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Put(' '); 3623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (key->IsString()) { 3633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Put(String::cast(key)); 3643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch key->ShortPrint(); 3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Add(": "); 3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* value = js_object->FastPropertyAt(descs->GetFieldIndex(i)); 3693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Add("%o\n", value); 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::PrintFixedArray(FixedArray* array, unsigned int limit) { 37744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Heap* heap = HEAP; 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (unsigned int i = 0; i < 10 && i < limit; i++) { 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* element = array->get(i); 38044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (element != heap->the_hole_value()) { 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int len = 1; len < 18; len++) 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Put(' '); 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("%d: %o\n", i, array->get(i)); 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (limit >= 10) { 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(" ...\n"); 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::PrintByteArray(ByteArray* byte_array) { 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned int limit = byte_array->length(); 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (unsigned int i = 0; i < 10 && i < limit; i++) { 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte b = byte_array->get(i); 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(" %d: %3d 0x%02x", i, b, b); 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (b >= ' ' && b <= '~') { 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(" '%c'", b); 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (b == '\n') { 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(" '\n'"); 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (b == '\r') { 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(" '\r'"); 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (b >= 1 && b <= 26) { 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(" ^%c", b + 'A' - 1); 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("\n"); 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (limit >= 10) { 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(" ...\n"); 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::PrintMentionedObjectCache() { 41544f0eee88ff00398ff7f715fab053374d808c90dSteve Block DebugObjectCache* debug_object_cache = 41644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->string_stream_debug_object_cache(); 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("==== Key ============================================\n\n"); 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < debug_object_cache->length(); i++) { 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapObject* printee = (*debug_object_cache)[i]; 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(" #%d# %p: ", i, printee); 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block printee->ShortPrint(this); 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("\n"); 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (printee->IsJSObject()) { 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (printee->IsJSValue()) { 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add(" value(): %o\n", JSValue::cast(printee)->value()); 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintUsingMap(JSObject::cast(printee)); 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (printee->IsJSArray()) { 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSArray* array = JSArray::cast(printee); 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (array->HasFastElements()) { 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned int limit = FixedArray::cast(array->elements())->length(); 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned int length = 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static_cast<uint32_t>(JSArray::cast(array)->length()->Number()); 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (length < limit) limit = length; 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintFixedArray(FixedArray::cast(array->elements()), limit); 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (printee->IsByteArray()) { 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintByteArray(ByteArray::cast(printee)); 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (printee->IsFixedArray()) { 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned int limit = FixedArray::cast(printee)->length(); 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintFixedArray(FixedArray::cast(printee), limit); 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::PrintSecurityTokenIfChanged(Object* f) { 44944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 45044f0eee88ff00398ff7f715fab053374d808c90dSteve Block Heap* heap = isolate->heap(); 45144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!f->IsHeapObject() || !heap->Contains(HeapObject::cast(f))) { 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Map* map = HeapObject::cast(f)->map(); 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!map->IsHeapObject() || 45644f0eee88ff00398ff7f715fab053374d808c90dSteve Block !heap->Contains(map) || 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !map->IsMap() || 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !f->IsJSFunction()) { 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSFunction* fun = JSFunction::cast(f); 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* perhaps_context = fun->unchecked_context(); 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (perhaps_context->IsHeapObject() && 46544f0eee88ff00398ff7f715fab053374d808c90dSteve Block heap->Contains(HeapObject::cast(perhaps_context)) && 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block perhaps_context->IsContext()) { 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Context* context = fun->context(); 46844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!heap->Contains(context)) { 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("(Function context is outside heap)\n"); 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* token = context->global_context()->security_token(); 47344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (token != isolate->string_stream_current_security_token()) { 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("Security context: %o\n", token); 47544f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->set_string_stream_current_security_token(token); 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("(Function context is corrupt)\n"); 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::PrintFunction(Object* f, Object* receiver, Code** code) { 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (f->IsHeapObject() && 48544f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->Contains(HeapObject::cast(f)) && 48644f0eee88ff00398ff7f715fab053374d808c90dSteve Block HEAP->Contains(HeapObject::cast(f)->map()) && 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapObject::cast(f)->map()->IsMap()) { 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (f->IsJSFunction()) { 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSFunction* fun = JSFunction::cast(f); 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Common case: on-stack function present and resolved. 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintPrototype(fun, receiver); 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *code = fun->code(); 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (f->IsSymbol()) { 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Unresolved and megamorphic calls: Instead of the function 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // we have the function name on the stack. 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintName(f); 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("/* unresolved */ "); 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Unless this is the frame of a built-in function, we should always have 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the callee function or name on the stack. If we don't, we have a 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // problem or a change of the stack frame layout. 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("%o", f); 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("/* warning: no JSFunction object or function name found */ "); 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block /* } else if (is_trampoline()) { 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Print("trampoline "); 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */ 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!f->IsHeapObject()) { 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("/* warning: 'function' was not a heap object */ "); 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 51344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!HEAP->Contains(HeapObject::cast(f))) { 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("/* warning: 'function' was not on the heap */ "); 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 51744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!HEAP->Contains(HeapObject::cast(f)->map())) { 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("/* warning: function's map was not on the heap */ "); 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!HeapObject::cast(f)->map()->IsMap()) { 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("/* warning: function's map was not a valid map */ "); 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return; 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("/* warning: Invalid JSFunction object found */ "); 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StringStream::PrintPrototype(JSFunction* fun, Object* receiver) { 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* name = fun->shared()->name(); 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool print_name = false; 53344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Heap* heap = HEAP; 53444f0eee88ff00398ff7f715fab053374d808c90dSteve Block for (Object* p = receiver; p != heap->null_value(); p = p->GetPrototype()) { 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (p->IsJSObject()) { 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* key = JSObject::cast(p)->SlowReverseLookup(fun); 53744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (key != heap->undefined_value()) { 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!name->IsString() || 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !key->IsString() || 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !String::cast(name)->Equals(String::cast(key))) { 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print_name = true; 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (name->IsString() && String::cast(name)->length() == 0) { 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print_name = false; 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block name = key; 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block print_name = true; 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintName(name); 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Also known as - if the name in the function doesn't match the name under 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // which it was looked up. 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (print_name) { 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Add("(aka "); 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PrintName(fun->shared()->name()); 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Put(')'); 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* HeapStringAllocator::grow(unsigned* bytes) { 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block unsigned new_bytes = *bytes * 2; 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Check for overflow. 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (new_bytes <= *bytes) { 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return space_; 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* new_space = NewArray<char>(new_bytes); 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (new_space == NULL) { 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return space_; 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memcpy(new_space, space_, *bytes); 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *bytes = new_bytes; 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(space_); 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block space_ = new_space; 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return new_space; 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Only grow once to the maximum allowable size. 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* NoAllocationStringAllocator::grow(unsigned* bytes) { 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(size_ >= *bytes); 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *bytes = size_; 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return space_; 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 590