Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(334)

Side by Side Diff: src/api.cc

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/accessors.cc ('k') | src/arm/assembler-thumb2.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 ScriptData* ScriptData::New(unsigned* data, int length) { 1100 ScriptData* ScriptData::New(unsigned* data, int length) {
1101 return new i::ScriptDataImpl(i::Vector<unsigned>(data, length)); 1101 return new i::ScriptDataImpl(i::Vector<unsigned>(data, length));
1102 } 1102 }
1103 1103
1104 1104
1105 // --- S c r i p t --- 1105 // --- S c r i p t ---
1106 1106
1107 1107
1108 Local<Script> Script::New(v8::Handle<String> source, 1108 Local<Script> Script::New(v8::Handle<String> source,
1109 v8::ScriptOrigin* origin, 1109 v8::ScriptOrigin* origin,
1110 v8::ScriptData* script_data) { 1110 v8::ScriptData* pre_data,
1111 v8::Handle<String> script_data) {
1111 ON_BAILOUT("v8::Script::New()", return Local<Script>()); 1112 ON_BAILOUT("v8::Script::New()", return Local<Script>());
1112 LOG_API("Script::New"); 1113 LOG_API("Script::New");
1113 ENTER_V8; 1114 ENTER_V8;
1114 i::Handle<i::String> str = Utils::OpenHandle(*source); 1115 i::Handle<i::String> str = Utils::OpenHandle(*source);
1115 i::Handle<i::Object> name_obj; 1116 i::Handle<i::Object> name_obj;
1116 int line_offset = 0; 1117 int line_offset = 0;
1117 int column_offset = 0; 1118 int column_offset = 0;
1118 if (origin != NULL) { 1119 if (origin != NULL) {
1119 if (!origin->ResourceName().IsEmpty()) { 1120 if (!origin->ResourceName().IsEmpty()) {
1120 name_obj = Utils::OpenHandle(*origin->ResourceName()); 1121 name_obj = Utils::OpenHandle(*origin->ResourceName());
1121 } 1122 }
1122 if (!origin->ResourceLineOffset().IsEmpty()) { 1123 if (!origin->ResourceLineOffset().IsEmpty()) {
1123 line_offset = static_cast<int>(origin->ResourceLineOffset()->Value()); 1124 line_offset = static_cast<int>(origin->ResourceLineOffset()->Value());
1124 } 1125 }
1125 if (!origin->ResourceColumnOffset().IsEmpty()) { 1126 if (!origin->ResourceColumnOffset().IsEmpty()) {
1126 column_offset = static_cast<int>(origin->ResourceColumnOffset()->Value()); 1127 column_offset = static_cast<int>(origin->ResourceColumnOffset()->Value());
1127 } 1128 }
1128 } 1129 }
1129 EXCEPTION_PREAMBLE(); 1130 EXCEPTION_PREAMBLE();
1130 i::ScriptDataImpl* pre_data = static_cast<i::ScriptDataImpl*>(script_data); 1131 i::ScriptDataImpl* pre_data_impl = static_cast<i::ScriptDataImpl*>(pre_data);
1131 // We assert that the pre-data is sane, even though we can actually 1132 // We assert that the pre-data is sane, even though we can actually
1132 // handle it if it turns out not to be in release mode. 1133 // handle it if it turns out not to be in release mode.
1133 ASSERT(pre_data == NULL || pre_data->SanityCheck()); 1134 ASSERT(pre_data_impl == NULL || pre_data_impl->SanityCheck());
1134 // If the pre-data isn't sane we simply ignore it 1135 // If the pre-data isn't sane we simply ignore it
1135 if (pre_data != NULL && !pre_data->SanityCheck()) { 1136 if (pre_data_impl != NULL && !pre_data_impl->SanityCheck()) {
1136 pre_data = NULL; 1137 pre_data_impl = NULL;
1137 } 1138 }
1138 i::Handle<i::JSFunction> boilerplate = 1139 i::Handle<i::JSFunction> boilerplate =
1139 i::Compiler::Compile(str, 1140 i::Compiler::Compile(str,
1140 name_obj, 1141 name_obj,
1141 line_offset, 1142 line_offset,
1142 column_offset, 1143 column_offset,
1143 NULL, 1144 NULL,
1144 pre_data, 1145 pre_data_impl,
1146 Utils::OpenHandle(*script_data),
1145 i::NOT_NATIVES_CODE); 1147 i::NOT_NATIVES_CODE);
1146 has_pending_exception = boilerplate.is_null(); 1148 has_pending_exception = boilerplate.is_null();
1147 EXCEPTION_BAILOUT_CHECK(Local<Script>()); 1149 EXCEPTION_BAILOUT_CHECK(Local<Script>());
1148 return Local<Script>(ToApi<Script>(boilerplate)); 1150 return Local<Script>(ToApi<Script>(boilerplate));
1149 } 1151 }
1150 1152
1151 1153
1152 Local<Script> Script::New(v8::Handle<String> source, 1154 Local<Script> Script::New(v8::Handle<String> source,
1153 v8::Handle<Value> file_name) { 1155 v8::Handle<Value> file_name) {
1154 ScriptOrigin origin(file_name); 1156 ScriptOrigin origin(file_name);
1155 return New(source, &origin); 1157 return New(source, &origin);
1156 } 1158 }
1157 1159
1158 1160
1159 Local<Script> Script::Compile(v8::Handle<String> source, 1161 Local<Script> Script::Compile(v8::Handle<String> source,
1160 v8::ScriptOrigin* origin, 1162 v8::ScriptOrigin* origin,
1161 v8::ScriptData* script_data) { 1163 v8::ScriptData* pre_data,
1164 v8::Handle<String> script_data) {
1162 ON_BAILOUT("v8::Script::Compile()", return Local<Script>()); 1165 ON_BAILOUT("v8::Script::Compile()", return Local<Script>());
1163 LOG_API("Script::Compile"); 1166 LOG_API("Script::Compile");
1164 ENTER_V8; 1167 ENTER_V8;
1165 Local<Script> generic = New(source, origin, script_data); 1168 Local<Script> generic = New(source, origin, pre_data, script_data);
1166 if (generic.IsEmpty()) 1169 if (generic.IsEmpty())
1167 return generic; 1170 return generic;
1168 i::Handle<i::JSFunction> boilerplate = Utils::OpenHandle(*generic); 1171 i::Handle<i::JSFunction> boilerplate = Utils::OpenHandle(*generic);
1169 i::Handle<i::JSFunction> result = 1172 i::Handle<i::JSFunction> result =
1170 i::Factory::NewFunctionFromBoilerplate(boilerplate, 1173 i::Factory::NewFunctionFromBoilerplate(boilerplate,
1171 i::Top::global_context()); 1174 i::Top::global_context());
1172 return Local<Script>(ToApi<Script>(result)); 1175 return Local<Script>(ToApi<Script>(result));
1173 } 1176 }
1174 1177
1175 1178
1176 Local<Script> Script::Compile(v8::Handle<String> source, 1179 Local<Script> Script::Compile(v8::Handle<String> source,
1177 v8::Handle<Value> file_name) { 1180 v8::Handle<Value> file_name,
1181 v8::Handle<String> script_data) {
1178 ScriptOrigin origin(file_name); 1182 ScriptOrigin origin(file_name);
1179 return Compile(source, &origin); 1183 return Compile(source, &origin, 0, script_data);
1180 } 1184 }
1181 1185
1182 1186
1183 Local<Value> Script::Run() { 1187 Local<Value> Script::Run() {
1184 ON_BAILOUT("v8::Script::Run()", return Local<Value>()); 1188 ON_BAILOUT("v8::Script::Run()", return Local<Value>());
1185 LOG_API("Script::Run"); 1189 LOG_API("Script::Run");
1186 ENTER_V8; 1190 ENTER_V8;
1187 i::Object* raw_result = NULL; 1191 i::Object* raw_result = NULL;
1188 { 1192 {
1189 HandleScope scope; 1193 HandleScope scope;
(...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after
2028 2032
2029 Local<Value> v8::Object::GetPrototype() { 2033 Local<Value> v8::Object::GetPrototype() {
2030 ON_BAILOUT("v8::Object::GetPrototype()", return Local<v8::Value>()); 2034 ON_BAILOUT("v8::Object::GetPrototype()", return Local<v8::Value>());
2031 ENTER_V8; 2035 ENTER_V8;
2032 i::Handle<i::Object> self = Utils::OpenHandle(this); 2036 i::Handle<i::Object> self = Utils::OpenHandle(this);
2033 i::Handle<i::Object> result = i::GetPrototype(self); 2037 i::Handle<i::Object> result = i::GetPrototype(self);
2034 return Utils::ToLocal(result); 2038 return Utils::ToLocal(result);
2035 } 2039 }
2036 2040
2037 2041
2042 bool v8::Object::SetPrototype(Handle<Value> value) {
2043 ON_BAILOUT("v8::Object::SetPrototype()", return false);
2044 ENTER_V8;
2045 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
2046 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
2047 EXCEPTION_PREAMBLE();
2048 i::Handle<i::Object> result = i::SetPrototype(self, value_obj);
2049 has_pending_exception = result.is_null();
2050 EXCEPTION_BAILOUT_CHECK(false);
2051 return true;
2052 }
2053
2054
2038 Local<Object> v8::Object::FindInstanceInPrototypeChain( 2055 Local<Object> v8::Object::FindInstanceInPrototypeChain(
2039 v8::Handle<FunctionTemplate> tmpl) { 2056 v8::Handle<FunctionTemplate> tmpl) {
2040 ON_BAILOUT("v8::Object::FindInstanceInPrototypeChain()", 2057 ON_BAILOUT("v8::Object::FindInstanceInPrototypeChain()",
2041 return Local<v8::Object>()); 2058 return Local<v8::Object>());
2042 ENTER_V8; 2059 ENTER_V8;
2043 i::JSObject* object = *Utils::OpenHandle(this); 2060 i::JSObject* object = *Utils::OpenHandle(this);
2044 i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl); 2061 i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
2045 while (!object->IsInstanceOf(tmpl_info)) { 2062 while (!object->IsInstanceOf(tmpl_info)) {
2046 i::Object* prototype = object->GetPrototype(); 2063 i::Object* prototype = object->GetPrototype();
2047 if (!prototype->IsJSObject()) return Local<Object>(); 2064 if (!prototype->IsJSObject()) return Local<Object>();
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
2190 2207
2191 Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain( 2208 Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
2192 Handle<String> key) { 2209 Handle<String> key) {
2193 ON_BAILOUT("v8::Object::GetRealNamedPropertyInPrototypeChain()", 2210 ON_BAILOUT("v8::Object::GetRealNamedPropertyInPrototypeChain()",
2194 return Local<Value>()); 2211 return Local<Value>());
2195 ENTER_V8; 2212 ENTER_V8;
2196 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this); 2213 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
2197 i::Handle<i::String> key_obj = Utils::OpenHandle(*key); 2214 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2198 i::LookupResult lookup; 2215 i::LookupResult lookup;
2199 self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup); 2216 self_obj->LookupRealNamedPropertyInPrototypes(*key_obj, &lookup);
2200 if (lookup.IsValid()) { 2217 if (lookup.IsProperty()) {
2201 PropertyAttributes attributes; 2218 PropertyAttributes attributes;
2202 i::Handle<i::Object> result(self_obj->GetProperty(*self_obj, 2219 i::Handle<i::Object> result(self_obj->GetProperty(*self_obj,
2203 &lookup, 2220 &lookup,
2204 *key_obj, 2221 *key_obj,
2205 &attributes)); 2222 &attributes));
2206 return Utils::ToLocal(result); 2223 return Utils::ToLocal(result);
2207 } 2224 }
2208 return Local<Value>(); // No real property was found in prototype chain. 2225 return Local<Value>(); // No real property was found in prototype chain.
2209 } 2226 }
2210 2227
2211 2228
2212 Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) { 2229 Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
2213 ON_BAILOUT("v8::Object::GetRealNamedProperty()", return Local<Value>()); 2230 ON_BAILOUT("v8::Object::GetRealNamedProperty()", return Local<Value>());
2214 ENTER_V8; 2231 ENTER_V8;
2215 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this); 2232 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
2216 i::Handle<i::String> key_obj = Utils::OpenHandle(*key); 2233 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
2217 i::LookupResult lookup; 2234 i::LookupResult lookup;
2218 self_obj->LookupRealNamedProperty(*key_obj, &lookup); 2235 self_obj->LookupRealNamedProperty(*key_obj, &lookup);
2219 if (lookup.IsValid()) { 2236 if (lookup.IsProperty()) {
2220 PropertyAttributes attributes; 2237 PropertyAttributes attributes;
2221 i::Handle<i::Object> result(self_obj->GetProperty(*self_obj, 2238 i::Handle<i::Object> result(self_obj->GetProperty(*self_obj,
2222 &lookup, 2239 &lookup,
2223 *key_obj, 2240 *key_obj,
2224 &attributes)); 2241 &attributes));
2225 return Utils::ToLocal(result); 2242 return Utils::ToLocal(result);
2226 } 2243 }
2227 return Local<Value>(); // No real property was found in prototype chain. 2244 return Local<Value>(); // No real property was found in prototype chain.
2228 } 2245 }
2229 2246
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
2441 func->shared()->set_name(*Utils::OpenHandle(*name)); 2458 func->shared()->set_name(*Utils::OpenHandle(*name));
2442 } 2459 }
2443 2460
2444 2461
2445 Handle<Value> Function::GetName() const { 2462 Handle<Value> Function::GetName() const {
2446 i::Handle<i::JSFunction> func = Utils::OpenHandle(this); 2463 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
2447 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name())); 2464 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name()));
2448 } 2465 }
2449 2466
2450 2467
2468 ScriptOrigin Function::GetScriptOrigin() const {
2469 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
2470 if (func->shared()->script()->IsScript()) {
2471 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
2472 v8::ScriptOrigin origin(
2473 Utils::ToLocal(i::Handle<i::Object>(script->name())),
2474 v8::Integer::New(script->line_offset()->value()),
2475 v8::Integer::New(script->column_offset()->value()));
2476 return origin;
2477 }
2478 return v8::ScriptOrigin(Handle<Value>());
2479 }
2480
2481
2482 const int Function::kLineOffsetNotFound = -1;
2483
2484
2485 int Function::GetScriptLineNumber() const {
2486 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
2487 if (func->shared()->script()->IsScript()) {
2488 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
2489 return i::GetScriptLineNumber(script, func->shared()->start_position());
2490 }
2491 return kLineOffsetNotFound;
2492 }
2493
2494
2495 namespace {
2496
2497 // Tracks string usage to help make better decisions when
2498 // externalizing strings.
2499 //
2500 // Implementation note: internally this class only tracks fresh
2501 // strings and keeps a single use counter for them.
2502 class StringTracker {
2503 public:
2504 // Records that the given string's characters were copied to some
2505 // external buffer. If this happens often we should honor
2506 // externalization requests for the string.
2507 static void RecordWrite(i::Handle<i::String> string) {
2508 i::Address address = reinterpret_cast<i::Address>(*string);
2509 i::Address top = i::Heap::NewSpaceTop();
2510 if (IsFreshString(address, top)) {
2511 IncrementUseCount(top);
2512 }
2513 }
2514
2515 // Estimates freshness and use frequency of the given string based
2516 // on how close it is to the new space top and the recorded usage
2517 // history.
2518 static inline bool IsFreshUnusedString(i::Handle<i::String> string) {
2519 i::Address address = reinterpret_cast<i::Address>(*string);
2520 i::Address top = i::Heap::NewSpaceTop();
2521 return IsFreshString(address, top) && IsUseCountLow(top);
2522 }
2523
2524 private:
2525 static inline bool IsFreshString(i::Address string, i::Address top) {
2526 return top - kFreshnessLimit <= string && string <= top;
2527 }
2528
2529 static inline bool IsUseCountLow(i::Address top) {
2530 if (last_top_ != top) return true;
2531 return use_count_ < kUseLimit;
2532 }
2533
2534 static inline void IncrementUseCount(i::Address top) {
2535 if (last_top_ != top) {
2536 use_count_ = 0;
2537 last_top_ = top;
2538 }
2539 ++use_count_;
2540 }
2541
2542 // How close to the new space top a fresh string has to be.
2543 static const int kFreshnessLimit = 1024;
2544
2545 // The number of uses required to consider a string useful.
2546 static const int kUseLimit = 32;
2547
2548 // Single use counter shared by all fresh strings.
2549 static int use_count_;
2550
2551 // Last new space top when the use count above was valid.
2552 static i::Address last_top_;
2553 };
2554
2555 int StringTracker::use_count_ = 0;
2556 i::Address StringTracker::last_top_ = NULL;
2557
2558 } // namespace
2559
2560
2451 int String::Length() const { 2561 int String::Length() const {
2452 if (IsDeadCheck("v8::String::Length()")) return 0; 2562 if (IsDeadCheck("v8::String::Length()")) return 0;
2453 return Utils::OpenHandle(this)->length(); 2563 return Utils::OpenHandle(this)->length();
2454 } 2564 }
2455 2565
2456 2566
2457 int String::Utf8Length() const { 2567 int String::Utf8Length() const {
2458 if (IsDeadCheck("v8::String::Utf8Length()")) return 0; 2568 if (IsDeadCheck("v8::String::Utf8Length()")) return 0;
2459 return Utils::OpenHandle(this)->Utf8Length(); 2569 return Utils::OpenHandle(this)->Utf8Length();
2460 } 2570 }
2461 2571
2462 2572
2463 int String::WriteUtf8(char* buffer, int capacity) const { 2573 int String::WriteUtf8(char* buffer, int capacity) const {
2464 if (IsDeadCheck("v8::String::WriteUtf8()")) return 0; 2574 if (IsDeadCheck("v8::String::WriteUtf8()")) return 0;
2465 LOG_API("String::WriteUtf8"); 2575 LOG_API("String::WriteUtf8");
2466 ENTER_V8; 2576 ENTER_V8;
2467 i::Handle<i::String> str = Utils::OpenHandle(this); 2577 i::Handle<i::String> str = Utils::OpenHandle(this);
2578 StringTracker::RecordWrite(str);
2468 write_input_buffer.Reset(0, *str); 2579 write_input_buffer.Reset(0, *str);
2469 int len = str->length(); 2580 int len = str->length();
2470 // Encode the first K - 3 bytes directly into the buffer since we 2581 // Encode the first K - 3 bytes directly into the buffer since we
2471 // know there's room for them. If no capacity is given we copy all 2582 // know there's room for them. If no capacity is given we copy all
2472 // of them here. 2583 // of them here.
2473 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1); 2584 int fast_end = capacity - (unibrow::Utf8::kMaxEncodedSize - 1);
2474 int i; 2585 int i;
2475 int pos = 0; 2586 int pos = 0;
2476 for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) { 2587 for (i = 0; i < len && (capacity == -1 || pos < fast_end); i++) {
2477 i::uc32 c = write_input_buffer.GetNext(); 2588 i::uc32 c = write_input_buffer.GetNext();
(...skipping 23 matching lines...) Expand all
2501 return pos; 2612 return pos;
2502 } 2613 }
2503 2614
2504 2615
2505 int String::WriteAscii(char* buffer, int start, int length) const { 2616 int String::WriteAscii(char* buffer, int start, int length) const {
2506 if (IsDeadCheck("v8::String::WriteAscii()")) return 0; 2617 if (IsDeadCheck("v8::String::WriteAscii()")) return 0;
2507 LOG_API("String::WriteAscii"); 2618 LOG_API("String::WriteAscii");
2508 ENTER_V8; 2619 ENTER_V8;
2509 ASSERT(start >= 0 && length >= -1); 2620 ASSERT(start >= 0 && length >= -1);
2510 i::Handle<i::String> str = Utils::OpenHandle(this); 2621 i::Handle<i::String> str = Utils::OpenHandle(this);
2622 StringTracker::RecordWrite(str);
2511 // Flatten the string for efficiency. This applies whether we are 2623 // Flatten the string for efficiency. This applies whether we are
2512 // using StringInputBuffer or Get(i) to access the characters. 2624 // using StringInputBuffer or Get(i) to access the characters.
2513 str->TryFlattenIfNotFlat(); 2625 str->TryFlattenIfNotFlat();
2514 int end = length; 2626 int end = length;
2515 if ( (length == -1) || (length > str->length() - start) ) 2627 if ( (length == -1) || (length > str->length() - start) )
2516 end = str->length() - start; 2628 end = str->length() - start;
2517 if (end < 0) return 0; 2629 if (end < 0) return 0;
2518 write_input_buffer.Reset(start, *str); 2630 write_input_buffer.Reset(start, *str);
2519 int i; 2631 int i;
2520 for (i = 0; i < end; i++) { 2632 for (i = 0; i < end; i++) {
2521 char c = static_cast<char>(write_input_buffer.GetNext()); 2633 char c = static_cast<char>(write_input_buffer.GetNext());
2522 if (c == '\0') c = ' '; 2634 if (c == '\0') c = ' ';
2523 buffer[i] = c; 2635 buffer[i] = c;
2524 } 2636 }
2525 if (length == -1 || i < length) 2637 if (length == -1 || i < length)
2526 buffer[i] = '\0'; 2638 buffer[i] = '\0';
2527 return i; 2639 return i;
2528 } 2640 }
2529 2641
2530 2642
2531 int String::Write(uint16_t* buffer, int start, int length) const { 2643 int String::Write(uint16_t* buffer, int start, int length) const {
2532 if (IsDeadCheck("v8::String::Write()")) return 0; 2644 if (IsDeadCheck("v8::String::Write()")) return 0;
2533 LOG_API("String::Write"); 2645 LOG_API("String::Write");
2534 ENTER_V8; 2646 ENTER_V8;
2535 ASSERT(start >= 0 && length >= -1); 2647 ASSERT(start >= 0 && length >= -1);
2536 i::Handle<i::String> str = Utils::OpenHandle(this); 2648 i::Handle<i::String> str = Utils::OpenHandle(this);
2649 StringTracker::RecordWrite(str);
2537 int end = length; 2650 int end = length;
2538 if ( (length == -1) || (length > str->length() - start) ) 2651 if ( (length == -1) || (length > str->length() - start) )
2539 end = str->length() - start; 2652 end = str->length() - start;
2540 if (end < 0) return 0; 2653 if (end < 0) return 0;
2541 i::String::WriteToFlat(*str, buffer, start, end); 2654 i::String::WriteToFlat(*str, buffer, start, end);
2542 if (length == -1 || end < length) 2655 if (length == -1 || end < length)
2543 buffer[end] = '\0'; 2656 buffer[end] = '\0';
2544 return end; 2657 return end;
2545 } 2658 }
2546 2659
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
3095 i::ExternalStringTable::AddString(*result); 3208 i::ExternalStringTable::AddString(*result);
3096 return Utils::ToLocal(result); 3209 return Utils::ToLocal(result);
3097 } 3210 }
3098 3211
3099 3212
3100 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) { 3213 bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
3101 if (IsDeadCheck("v8::String::MakeExternal()")) return false; 3214 if (IsDeadCheck("v8::String::MakeExternal()")) return false;
3102 if (this->IsExternal()) return false; // Already an external string. 3215 if (this->IsExternal()) return false; // Already an external string.
3103 ENTER_V8; 3216 ENTER_V8;
3104 i::Handle<i::String> obj = Utils::OpenHandle(this); 3217 i::Handle<i::String> obj = Utils::OpenHandle(this);
3218 if (StringTracker::IsFreshUnusedString(obj)) return false;
3105 bool result = obj->MakeExternal(resource); 3219 bool result = obj->MakeExternal(resource);
3106 if (result && !obj->IsSymbol()) { 3220 if (result && !obj->IsSymbol()) {
3107 i::ExternalStringTable::AddString(*obj); 3221 i::ExternalStringTable::AddString(*obj);
3108 } 3222 }
3109 return result; 3223 return result;
3110 } 3224 }
3111 3225
3112 3226
3113 Local<String> v8::String::NewExternal( 3227 Local<String> v8::String::NewExternal(
3114 v8::String::ExternalAsciiStringResource* resource) { 3228 v8::String::ExternalAsciiStringResource* resource) {
3115 EnsureInitialized("v8::String::NewExternal()"); 3229 EnsureInitialized("v8::String::NewExternal()");
3116 LOG_API("String::NewExternal"); 3230 LOG_API("String::NewExternal");
3117 ENTER_V8; 3231 ENTER_V8;
3118 i::Handle<i::String> result = NewExternalAsciiStringHandle(resource); 3232 i::Handle<i::String> result = NewExternalAsciiStringHandle(resource);
3119 i::ExternalStringTable::AddString(*result); 3233 i::ExternalStringTable::AddString(*result);
3120 return Utils::ToLocal(result); 3234 return Utils::ToLocal(result);
3121 } 3235 }
3122 3236
3123 3237
3124 bool v8::String::MakeExternal( 3238 bool v8::String::MakeExternal(
3125 v8::String::ExternalAsciiStringResource* resource) { 3239 v8::String::ExternalAsciiStringResource* resource) {
3126 if (IsDeadCheck("v8::String::MakeExternal()")) return false; 3240 if (IsDeadCheck("v8::String::MakeExternal()")) return false;
3127 if (this->IsExternal()) return false; // Already an external string. 3241 if (this->IsExternal()) return false; // Already an external string.
3128 ENTER_V8; 3242 ENTER_V8;
3129 i::Handle<i::String> obj = Utils::OpenHandle(this); 3243 i::Handle<i::String> obj = Utils::OpenHandle(this);
3244 if (StringTracker::IsFreshUnusedString(obj)) return false;
3130 bool result = obj->MakeExternal(resource); 3245 bool result = obj->MakeExternal(resource);
3131 if (result && !obj->IsSymbol()) { 3246 if (result && !obj->IsSymbol()) {
3132 i::ExternalStringTable::AddString(*obj); 3247 i::ExternalStringTable::AddString(*obj);
3133 } 3248 }
3134 return result; 3249 return result;
3135 } 3250 }
3136 3251
3137 3252
3138 bool v8::String::CanMakeExternal() { 3253 bool v8::String::CanMakeExternal() {
3139 if (IsDeadCheck("v8::String::CanMakeExternal()")) return false; 3254 if (IsDeadCheck("v8::String::CanMakeExternal()")) return false;
3140 i::Handle<i::String> obj = Utils::OpenHandle(this); 3255 i::Handle<i::String> obj = Utils::OpenHandle(this);
3256 if (StringTracker::IsFreshUnusedString(obj)) return false;
3141 int size = obj->Size(); // Byte size of the original string. 3257 int size = obj->Size(); // Byte size of the original string.
3142 if (size < i::ExternalString::kSize) 3258 if (size < i::ExternalString::kSize)
3143 return false; 3259 return false;
3144 i::StringShape shape(*obj); 3260 i::StringShape shape(*obj);
3145 return !shape.IsExternal(); 3261 return !shape.IsExternal();
3146 } 3262 }
3147 3263
3148 3264
3149 Local<v8::Object> v8::Object::New() { 3265 Local<v8::Object> v8::Object::New() {
3150 EnsureInitialized("v8::Object::New()"); 3266 EnsureInitialized("v8::Object::New()");
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
3354 3470
3355 3471
3356 void V8::SetGlobalGCEpilogueCallback(GCCallback callback) { 3472 void V8::SetGlobalGCEpilogueCallback(GCCallback callback) {
3357 if (IsDeadCheck("v8::V8::SetGlobalGCEpilogueCallback()")) return; 3473 if (IsDeadCheck("v8::V8::SetGlobalGCEpilogueCallback()")) return;
3358 i::Heap::SetGlobalGCEpilogueCallback(callback); 3474 i::Heap::SetGlobalGCEpilogueCallback(callback);
3359 } 3475 }
3360 3476
3361 3477
3362 void V8::PauseProfiler() { 3478 void V8::PauseProfiler() {
3363 #ifdef ENABLE_LOGGING_AND_PROFILING 3479 #ifdef ENABLE_LOGGING_AND_PROFILING
3364 i::Logger::PauseProfiler(PROFILER_MODULE_CPU); 3480 PauseProfilerEx(PROFILER_MODULE_CPU);
3365 #endif 3481 #endif
3366 } 3482 }
3367 3483
3368 3484
3369 void V8::ResumeProfiler() { 3485 void V8::ResumeProfiler() {
3370 #ifdef ENABLE_LOGGING_AND_PROFILING 3486 #ifdef ENABLE_LOGGING_AND_PROFILING
3371 i::Logger::ResumeProfiler(PROFILER_MODULE_CPU); 3487 ResumeProfilerEx(PROFILER_MODULE_CPU);
3372 #endif 3488 #endif
3373 } 3489 }
3374 3490
3375 3491
3376 bool V8::IsProfilerPaused() { 3492 bool V8::IsProfilerPaused() {
3377 #ifdef ENABLE_LOGGING_AND_PROFILING 3493 #ifdef ENABLE_LOGGING_AND_PROFILING
3378 return i::Logger::GetActiveProfilerModules() & PROFILER_MODULE_CPU; 3494 return i::Logger::GetActiveProfilerModules() & PROFILER_MODULE_CPU;
3379 #else 3495 #else
3380 return true; 3496 return true;
3381 #endif 3497 #endif
3382 } 3498 }
3383 3499
3384 3500
3385 void V8::ResumeProfilerEx(int flags) { 3501 void V8::ResumeProfilerEx(int flags, int tag) {
3386 #ifdef ENABLE_LOGGING_AND_PROFILING 3502 #ifdef ENABLE_LOGGING_AND_PROFILING
3387 if (flags & PROFILER_MODULE_HEAP_SNAPSHOT) { 3503 if (flags & PROFILER_MODULE_HEAP_SNAPSHOT) {
3388 // Snapshot mode: resume modules, perform GC, then pause only 3504 // Snapshot mode: resume modules, perform GC, then pause only
3389 // those modules which haven't been started prior to making a 3505 // those modules which haven't been started prior to making a
3390 // snapshot. 3506 // snapshot.
3391 3507
3392 // Reset snapshot flag and CPU module flags. 3508 // Reset snapshot flag and CPU module flags.
3393 flags &= ~(PROFILER_MODULE_HEAP_SNAPSHOT | PROFILER_MODULE_CPU); 3509 flags &= ~(PROFILER_MODULE_HEAP_SNAPSHOT | PROFILER_MODULE_CPU);
3394 const int current_flags = i::Logger::GetActiveProfilerModules(); 3510 const int current_flags = i::Logger::GetActiveProfilerModules();
3395 i::Logger::ResumeProfiler(flags); 3511 i::Logger::ResumeProfiler(flags, tag);
3396 i::Heap::CollectAllGarbage(false); 3512 i::Heap::CollectAllGarbage(false);
3397 i::Logger::PauseProfiler(~current_flags & flags); 3513 i::Logger::PauseProfiler(~current_flags & flags, tag);
3398 } else { 3514 } else {
3399 i::Logger::ResumeProfiler(flags); 3515 i::Logger::ResumeProfiler(flags, tag);
3400 } 3516 }
3401 #endif 3517 #endif
3402 } 3518 }
3403 3519
3404 3520
3405 void V8::PauseProfilerEx(int flags) { 3521 void V8::PauseProfilerEx(int flags, int tag) {
3406 #ifdef ENABLE_LOGGING_AND_PROFILING 3522 #ifdef ENABLE_LOGGING_AND_PROFILING
3407 i::Logger::PauseProfiler(flags); 3523 i::Logger::PauseProfiler(flags, tag);
3408 #endif 3524 #endif
3409 } 3525 }
3410 3526
3411 3527
3412 int V8::GetActiveProfilerModules() { 3528 int V8::GetActiveProfilerModules() {
3413 #ifdef ENABLE_LOGGING_AND_PROFILING 3529 #ifdef ENABLE_LOGGING_AND_PROFILING
3414 return i::Logger::GetActiveProfilerModules(); 3530 return i::Logger::GetActiveProfilerModules();
3415 #else 3531 #else
3416 return PROFILER_MODULE_NONE; 3532 return PROFILER_MODULE_NONE;
3417 #endif 3533 #endif
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
3830 3946
3831 3947
3832 char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) { 3948 char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
3833 HandleScopeImplementer* thread_local = 3949 HandleScopeImplementer* thread_local =
3834 reinterpret_cast<HandleScopeImplementer*>(storage); 3950 reinterpret_cast<HandleScopeImplementer*>(storage);
3835 thread_local->IterateThis(v); 3951 thread_local->IterateThis(v);
3836 return storage + ArchiveSpacePerThread(); 3952 return storage + ArchiveSpacePerThread();
3837 } 3953 }
3838 3954
3839 } } // namespace v8::internal 3955 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/accessors.cc ('k') | src/arm/assembler-thumb2.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698