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

Side by Side Diff: src/runtime.cc

Issue 146213004: A64: Synchronize with r16849. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 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/runtime.h ('k') | src/runtime-profiler.cc » ('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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 // Update the functions literal and return the boilerplate. 499 // Update the functions literal and return the boilerplate.
500 literals->set(literals_index, *boilerplate); 500 literals->set(literals_index, *boilerplate);
501 } 501 }
502 502
503 Handle<Object> copy = JSObject::DeepCopy(Handle<JSObject>::cast(boilerplate)); 503 Handle<Object> copy = JSObject::DeepCopy(Handle<JSObject>::cast(boilerplate));
504 RETURN_IF_EMPTY_HANDLE(isolate, copy); 504 RETURN_IF_EMPTY_HANDLE(isolate, copy);
505 return *copy; 505 return *copy;
506 } 506 }
507 507
508 508
509 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectLiteralShallow) {
510 HandleScope scope(isolate);
511 ASSERT(args.length() == 4);
512 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
513 CONVERT_SMI_ARG_CHECKED(literals_index, 1);
514 CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
515 CONVERT_SMI_ARG_CHECKED(flags, 3);
516 bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
517 bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
518
519 // Check if boilerplate exists. If not, create it first.
520 Handle<Object> boilerplate(literals->get(literals_index), isolate);
521 if (*boilerplate == isolate->heap()->undefined_value()) {
522 boilerplate = CreateObjectLiteralBoilerplate(isolate,
523 literals,
524 constant_properties,
525 should_have_fast_elements,
526 has_function_literal);
527 RETURN_IF_EMPTY_HANDLE(isolate, boilerplate);
528 // Update the functions literal and return the boilerplate.
529 literals->set(literals_index, *boilerplate);
530 }
531 return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate));
532 }
533
534
535 static Handle<AllocationSite> GetLiteralAllocationSite( 509 static Handle<AllocationSite> GetLiteralAllocationSite(
536 Isolate* isolate, 510 Isolate* isolate,
537 Handle<FixedArray> literals, 511 Handle<FixedArray> literals,
538 int literals_index, 512 int literals_index,
539 Handle<FixedArray> elements) { 513 Handle<FixedArray> elements) {
540 // Check if boilerplate exists. If not, create it first. 514 // Check if boilerplate exists. If not, create it first.
541 Handle<Object> literal_site(literals->get(literals_index), isolate); 515 Handle<Object> literal_site(literals->get(literals_index), isolate);
542 Handle<AllocationSite> site; 516 Handle<AllocationSite> site;
543 if (*literal_site == isolate->heap()->undefined_value()) { 517 if (*literal_site == isolate->heap()->undefined_value()) {
544 ASSERT(*elements != isolate->heap()->empty_fixed_array()); 518 ASSERT(*elements != isolate->heap()->empty_fixed_array());
(...skipping 1617 matching lines...) Expand 10 before | Expand all | Expand 10 after
2162 ASSERT(context->IsFunctionContext()); 2136 ASSERT(context->IsFunctionContext());
2163 object = isolate->factory()->NewJSObject( 2137 object = isolate->factory()->NewJSObject(
2164 isolate->context_extension_function()); 2138 isolate->context_extension_function());
2165 context->set_extension(*object); 2139 context->set_extension(*object);
2166 } 2140 }
2167 ASSERT(*object != NULL); 2141 ASSERT(*object != NULL);
2168 2142
2169 // Declare the property by setting it to the initial value if provided, 2143 // Declare the property by setting it to the initial value if provided,
2170 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for 2144 // or undefined, and use the correct mode (e.g. READ_ONLY attribute for
2171 // constant declarations). 2145 // constant declarations).
2172 ASSERT(!object->HasLocalProperty(*name)); 2146 ASSERT(!JSReceiver::HasLocalProperty(object, name));
2173 Handle<Object> value(isolate->heap()->undefined_value(), isolate); 2147 Handle<Object> value(isolate->heap()->undefined_value(), isolate);
2174 if (*initial_value != NULL) value = initial_value; 2148 if (*initial_value != NULL) value = initial_value;
2175 // Declaring a const context slot is a conflicting declaration if 2149 // Declaring a const context slot is a conflicting declaration if
2176 // there is a callback with that name in a prototype. It is 2150 // there is a callback with that name in a prototype. It is
2177 // allowed to introduce const variables in 2151 // allowed to introduce const variables in
2178 // JSContextExtensionObjects. They are treated specially in 2152 // JSContextExtensionObjects. They are treated specially in
2179 // SetProperty and no setters are invoked for those since they are 2153 // SetProperty and no setters are invoked for those since they are
2180 // not real JSObjects. 2154 // not real JSObjects.
2181 if (initial_value->IsTheHole() && 2155 if (initial_value->IsTheHole() &&
2182 !object->IsJSContextExtensionObject()) { 2156 !object->IsJSContextExtensionObject()) {
(...skipping 11 matching lines...) Expand all
2194 RETURN_IF_EMPTY_HANDLE(isolate, 2168 RETURN_IF_EMPTY_HANDLE(isolate,
2195 JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode)); 2169 JSReceiver::SetProperty(object, name, value, mode, kNonStrictMode));
2196 } 2170 }
2197 } 2171 }
2198 2172
2199 return isolate->heap()->undefined_value(); 2173 return isolate->heap()->undefined_value();
2200 } 2174 }
2201 2175
2202 2176
2203 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) { 2177 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeVarGlobal) {
2204 SealHandleScope shs(isolate); 2178 HandleScope scope(isolate);
2205 // args[0] == name 2179 // args[0] == name
2206 // args[1] == language_mode 2180 // args[1] == language_mode
2207 // args[2] == value (optional) 2181 // args[2] == value (optional)
2208 2182
2209 // Determine if we need to assign to the variable if it already 2183 // Determine if we need to assign to the variable if it already
2210 // exists (based on the number of arguments). 2184 // exists (based on the number of arguments).
2211 RUNTIME_ASSERT(args.length() == 2 || args.length() == 3); 2185 RUNTIME_ASSERT(args.length() == 2 || args.length() == 3);
2212 bool assign = args.length() == 3; 2186 bool assign = args.length() == 3;
2213 2187
2214 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 2188 CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
2215 GlobalObject* global = isolate->context()->global_object();
2216 RUNTIME_ASSERT(args[1]->IsSmi()); 2189 RUNTIME_ASSERT(args[1]->IsSmi());
2217 CONVERT_LANGUAGE_MODE_ARG(language_mode, 1); 2190 CONVERT_LANGUAGE_MODE_ARG(language_mode, 1);
2218 StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE) 2191 StrictModeFlag strict_mode_flag = (language_mode == CLASSIC_MODE)
2219 ? kNonStrictMode : kStrictMode; 2192 ? kNonStrictMode : kStrictMode;
2220 2193
2221 // According to ECMA-262, section 12.2, page 62, the property must 2194 // According to ECMA-262, section 12.2, page 62, the property must
2222 // not be deletable. 2195 // not be deletable.
2223 PropertyAttributes attributes = DONT_DELETE; 2196 PropertyAttributes attributes = DONT_DELETE;
2224 2197
2225 // Lookup the property locally in the global object. If it isn't 2198 // Lookup the property locally in the global object. If it isn't
2226 // there, there is a property with this name in the prototype chain. 2199 // there, there is a property with this name in the prototype chain.
2227 // We follow Safari and Firefox behavior and only set the property 2200 // We follow Safari and Firefox behavior and only set the property
2228 // locally if there is an explicit initialization value that we have 2201 // locally if there is an explicit initialization value that we have
2229 // to assign to the property. 2202 // to assign to the property.
2230 // Note that objects can have hidden prototypes, so we need to traverse 2203 // Note that objects can have hidden prototypes, so we need to traverse
2231 // the whole chain of hidden prototypes to do a 'local' lookup. 2204 // the whole chain of hidden prototypes to do a 'local' lookup.
2232 Object* object = global;
2233 LookupResult lookup(isolate); 2205 LookupResult lookup(isolate);
2234 JSObject::cast(object)->LocalLookup(*name, &lookup, true); 2206 isolate->context()->global_object()->LocalLookup(*name, &lookup, true);
2235 if (lookup.IsInterceptor()) { 2207 if (lookup.IsInterceptor()) {
2236 HandleScope handle_scope(isolate);
2237 PropertyAttributes intercepted = 2208 PropertyAttributes intercepted =
2238 lookup.holder()->GetPropertyAttribute(*name); 2209 lookup.holder()->GetPropertyAttribute(*name);
2239 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) { 2210 if (intercepted != ABSENT && (intercepted & READ_ONLY) == 0) {
2240 // Found an interceptor that's not read only. 2211 // Found an interceptor that's not read only.
2241 if (assign) { 2212 if (assign) {
2242 return lookup.holder()->SetProperty( 2213 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
2243 &lookup, *name, args[2], attributes, strict_mode_flag); 2214 Handle<Object> result = JSObject::SetPropertyForResult(
2215 handle(lookup.holder()), &lookup, name, value, attributes,
2216 strict_mode_flag);
2217 RETURN_IF_EMPTY_HANDLE(isolate, result);
2218 return *result;
2244 } else { 2219 } else {
2245 return isolate->heap()->undefined_value(); 2220 return isolate->heap()->undefined_value();
2246 } 2221 }
2247 } 2222 }
2248 } 2223 }
2249 2224
2250 // Reload global in case the loop above performed a GC.
2251 global = isolate->context()->global_object();
2252 if (assign) { 2225 if (assign) {
2253 return global->SetProperty(*name, args[2], attributes, strict_mode_flag); 2226 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
2227 Handle<GlobalObject> global(isolate->context()->global_object());
2228 Handle<Object> result = JSReceiver::SetProperty(
2229 global, name, value, attributes, strict_mode_flag);
2230 RETURN_IF_EMPTY_HANDLE(isolate, result);
2231 return *result;
2254 } 2232 }
2255 return isolate->heap()->undefined_value(); 2233 return isolate->heap()->undefined_value();
2256 } 2234 }
2257 2235
2258 2236
2259 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) { 2237 RUNTIME_FUNCTION(MaybeObject*, Runtime_InitializeConstGlobal) {
2260 SealHandleScope shs(isolate); 2238 SealHandleScope shs(isolate);
2261 // All constants are declared with an initial value. The name 2239 // All constants are declared with an initial value. The name
2262 // of the constant is the first argument and the initial value 2240 // of the constant is the first argument and the initial value
2263 // is the second. 2241 // is the second.
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after
3088 int continuation = generator->continuation(); 3066 int continuation = generator->continuation();
3089 const char* message = continuation == JSGeneratorObject::kGeneratorClosed ? 3067 const char* message = continuation == JSGeneratorObject::kGeneratorClosed ?
3090 "generator_finished" : "generator_running"; 3068 "generator_finished" : "generator_running";
3091 Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0); 3069 Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0);
3092 Handle<Object> error = isolate->factory()->NewError(message, argv); 3070 Handle<Object> error = isolate->factory()->NewError(message, argv);
3093 return isolate->Throw(*error); 3071 return isolate->Throw(*error);
3094 } 3072 }
3095 3073
3096 3074
3097 RUNTIME_FUNCTION(MaybeObject*, Runtime_ObjectFreeze) { 3075 RUNTIME_FUNCTION(MaybeObject*, Runtime_ObjectFreeze) {
3098 SealHandleScope shs(isolate); 3076 HandleScope scope(isolate);
3099 ASSERT(args.length() == 1); 3077 ASSERT(args.length() == 1);
3100 CONVERT_ARG_CHECKED(JSObject, object, 0); 3078 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
3101 return object->Freeze(isolate); 3079 Handle<Object> result = JSObject::Freeze(object);
3080 RETURN_IF_EMPTY_HANDLE(isolate, result);
3081 return *result;
3102 } 3082 }
3103 3083
3104 3084
3105 MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate, 3085 MUST_USE_RESULT static MaybeObject* CharFromCode(Isolate* isolate,
3106 Object* char_code) { 3086 Object* char_code) {
3107 if (char_code->IsNumber()) { 3087 if (char_code->IsNumber()) {
3108 return isolate->heap()->LookupSingleCharacterStringFromCode( 3088 return isolate->heap()->LookupSingleCharacterStringFromCode(
3109 NumberToUint32(char_code) & 0xffff); 3089 NumberToUint32(char_code) & 0xffff);
3110 } 3090 }
3111 return isolate->heap()->empty_string(); 3091 return isolate->heap()->empty_string();
(...skipping 1664 matching lines...) Expand 10 before | Expand all | Expand 10 after
4776 4756
4777 4757
4778 MaybeObject* Runtime::HasObjectProperty(Isolate* isolate, 4758 MaybeObject* Runtime::HasObjectProperty(Isolate* isolate,
4779 Handle<JSReceiver> object, 4759 Handle<JSReceiver> object,
4780 Handle<Object> key) { 4760 Handle<Object> key) {
4781 HandleScope scope(isolate); 4761 HandleScope scope(isolate);
4782 4762
4783 // Check if the given key is an array index. 4763 // Check if the given key is an array index.
4784 uint32_t index; 4764 uint32_t index;
4785 if (key->ToArrayIndex(&index)) { 4765 if (key->ToArrayIndex(&index)) {
4786 return isolate->heap()->ToBoolean(object->HasElement(index)); 4766 return isolate->heap()->ToBoolean(JSReceiver::HasElement(object, index));
4787 } 4767 }
4788 4768
4789 // Convert the key to a name - possibly by calling back into JavaScript. 4769 // Convert the key to a name - possibly by calling back into JavaScript.
4790 Handle<Name> name; 4770 Handle<Name> name;
4791 if (key->IsName()) { 4771 if (key->IsName()) {
4792 name = Handle<Name>::cast(key); 4772 name = Handle<Name>::cast(key);
4793 } else { 4773 } else {
4794 bool has_pending_exception = false; 4774 bool has_pending_exception = false;
4795 Handle<Object> converted = 4775 Handle<Object> converted =
4796 Execution::ToString(isolate, key, &has_pending_exception); 4776 Execution::ToString(isolate, key, &has_pending_exception);
4797 if (has_pending_exception) return Failure::Exception(); 4777 if (has_pending_exception) return Failure::Exception();
4798 name = Handle<Name>::cast(converted); 4778 name = Handle<Name>::cast(converted);
4799 } 4779 }
4800 4780
4801 return isolate->heap()->ToBoolean(object->HasProperty(*name)); 4781 return isolate->heap()->ToBoolean(JSReceiver::HasProperty(object, name));
4802 } 4782 }
4803 4783
4804 MaybeObject* Runtime::GetObjectPropertyOrFail( 4784 MaybeObject* Runtime::GetObjectPropertyOrFail(
4805 Isolate* isolate, 4785 Isolate* isolate,
4806 Handle<Object> object, 4786 Handle<Object> object,
4807 Handle<Object> key) { 4787 Handle<Object> key) {
4808 CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate, 4788 CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
4809 GetObjectProperty(isolate, object, key)); 4789 GetObjectProperty(isolate, object, key));
4810 } 4790 }
4811 4791
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
5026 // in Object.defineProperty(). Firefox disagrees here, and actually changes 5006 // in Object.defineProperty(). Firefox disagrees here, and actually changes
5027 // the value. 5007 // the value.
5028 if (callback->IsAccessorInfo()) { 5008 if (callback->IsAccessorInfo()) {
5029 return isolate->heap()->undefined_value(); 5009 return isolate->heap()->undefined_value();
5030 } 5010 }
5031 // Avoid redefining foreign callback as data property, just use the stored 5011 // Avoid redefining foreign callback as data property, just use the stored
5032 // setter to update the value instead. 5012 // setter to update the value instead.
5033 // TODO(mstarzinger): So far this only works if property attributes don't 5013 // TODO(mstarzinger): So far this only works if property attributes don't
5034 // change, this should be fixed once we cleanup the underlying code. 5014 // change, this should be fixed once we cleanup the underlying code.
5035 if (callback->IsForeign() && result.GetAttributes() == attr) { 5015 if (callback->IsForeign() && result.GetAttributes() == attr) {
5036 return js_object->SetPropertyWithCallback(callback, 5016 Handle<Object> result_object =
5037 *name, 5017 JSObject::SetPropertyWithCallback(js_object,
5038 *obj_value, 5018 handle(callback, isolate),
5039 result.holder(), 5019 name,
5040 kStrictMode); 5020 obj_value,
5021 handle(result.holder()),
5022 kStrictMode);
5023 RETURN_IF_EMPTY_HANDLE(isolate, result_object);
5024 return *result_object;
5041 } 5025 }
5042 } 5026 }
5043 5027
5044 // Take special care when attributes are different and there is already 5028 // Take special care when attributes are different and there is already
5045 // a property. For simplicity we normalize the property which enables us 5029 // a property. For simplicity we normalize the property which enables us
5046 // to not worry about changing the instance_descriptor and creating a new 5030 // to not worry about changing the instance_descriptor and creating a new
5047 // map. The current version of SetObjectProperty does not handle attributes 5031 // map. The current version of SetObjectProperty does not handle attributes
5048 // correctly in the case where a property is a field and is reset with 5032 // correctly in the case where a property is a field and is reset with
5049 // new attributes. 5033 // new attributes.
5050 if (result.IsFound() && 5034 if (result.IsFound() &&
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
5126 if (object->IsUndefined() || object->IsNull()) { 5110 if (object->IsUndefined() || object->IsNull()) {
5127 Handle<Object> args[2] = { key, object }; 5111 Handle<Object> args[2] = { key, object };
5128 Handle<Object> error = 5112 Handle<Object> error =
5129 isolate->factory()->NewTypeError("non_object_property_store", 5113 isolate->factory()->NewTypeError("non_object_property_store",
5130 HandleVector(args, 2)); 5114 HandleVector(args, 2));
5131 return isolate->Throw(*error); 5115 return isolate->Throw(*error);
5132 } 5116 }
5133 5117
5134 if (object->IsJSProxy()) { 5118 if (object->IsJSProxy()) {
5135 bool has_pending_exception = false; 5119 bool has_pending_exception = false;
5136 Handle<Object> name = key->IsSymbol() 5120 Handle<Object> name_object = key->IsSymbol()
5137 ? key : Execution::ToString(isolate, key, &has_pending_exception); 5121 ? key : Execution::ToString(isolate, key, &has_pending_exception);
5138 if (has_pending_exception) return Failure::Exception(); 5122 if (has_pending_exception) return Failure::Exception();
5139 return JSProxy::cast(*object)->SetProperty( 5123 Handle<Name> name = Handle<Name>::cast(name_object);
5140 Name::cast(*name), *value, attr, strict_mode); 5124 Handle<Object> result = JSReceiver::SetProperty(
5125 Handle<JSProxy>::cast(object), name, value, attr, strict_mode);
5126 RETURN_IF_EMPTY_HANDLE(isolate, result);
5127 return *result;
5141 } 5128 }
5142 5129
5143 // If the object isn't a JavaScript object, we ignore the store. 5130 // If the object isn't a JavaScript object, we ignore the store.
5144 if (!object->IsJSObject()) return *value; 5131 if (!object->IsJSObject()) return *value;
5145 5132
5146 Handle<JSObject> js_object = Handle<JSObject>::cast(object); 5133 Handle<JSObject> js_object = Handle<JSObject>::cast(object);
5147 5134
5148 // Check if the given key is an array index. 5135 // Check if the given key is an array index.
5149 uint32_t index; 5136 uint32_t index;
5150 if (key->ToArrayIndex(&index)) { 5137 if (key->ToArrayIndex(&index)) {
(...skipping 19 matching lines...) Expand all
5170 } 5157 }
5171 } 5158 }
5172 MaybeObject* result = js_object->SetElement( 5159 MaybeObject* result = js_object->SetElement(
5173 index, *value, attr, strict_mode, true, set_mode); 5160 index, *value, attr, strict_mode, true, set_mode);
5174 js_object->ValidateElements(); 5161 js_object->ValidateElements();
5175 if (result->IsFailure()) return result; 5162 if (result->IsFailure()) return result;
5176 return *value; 5163 return *value;
5177 } 5164 }
5178 5165
5179 if (key->IsName()) { 5166 if (key->IsName()) {
5180 MaybeObject* result;
5181 Handle<Name> name = Handle<Name>::cast(key); 5167 Handle<Name> name = Handle<Name>::cast(key);
5182 if (name->AsArrayIndex(&index)) { 5168 if (name->AsArrayIndex(&index)) {
5183 if (js_object->HasExternalArrayElements()) { 5169 if (js_object->HasExternalArrayElements()) {
5184 if (!value->IsNumber() && !value->IsUndefined()) { 5170 if (!value->IsNumber() && !value->IsUndefined()) {
5185 bool has_exception; 5171 bool has_exception;
5186 Handle<Object> number = 5172 Handle<Object> number =
5187 Execution::ToNumber(isolate, value, &has_exception); 5173 Execution::ToNumber(isolate, value, &has_exception);
5188 if (has_exception) return Failure::Exception(); 5174 if (has_exception) return Failure::Exception();
5189 value = number; 5175 value = number;
5190 } 5176 }
5191 } 5177 }
5192 result = js_object->SetElement( 5178 MaybeObject* result = js_object->SetElement(
5193 index, *value, attr, strict_mode, true, set_mode); 5179 index, *value, attr, strict_mode, true, set_mode);
5180 if (result->IsFailure()) return result;
5194 } else { 5181 } else {
5195 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); 5182 if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
5196 result = js_object->SetProperty(*name, *value, attr, strict_mode); 5183 Handle<Object> result =
5184 JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
5185 RETURN_IF_EMPTY_HANDLE(isolate, result);
5197 } 5186 }
5198 if (result->IsFailure()) return result;
5199 return *value; 5187 return *value;
5200 } 5188 }
5201 5189
5202 // Call-back into JavaScript to convert the key to a string. 5190 // Call-back into JavaScript to convert the key to a string.
5203 bool has_pending_exception = false; 5191 bool has_pending_exception = false;
5204 Handle<Object> converted = 5192 Handle<Object> converted =
5205 Execution::ToString(isolate, key, &has_pending_exception); 5193 Execution::ToString(isolate, key, &has_pending_exception);
5206 if (has_pending_exception) return Failure::Exception(); 5194 if (has_pending_exception) return Failure::Exception();
5207 Handle<String> name = Handle<String>::cast(converted); 5195 Handle<String> name = Handle<String>::cast(converted);
5208 5196
5209 if (name->AsArrayIndex(&index)) { 5197 if (name->AsArrayIndex(&index)) {
5210 return js_object->SetElement( 5198 return js_object->SetElement(
5211 index, *value, attr, strict_mode, true, set_mode); 5199 index, *value, attr, strict_mode, true, set_mode);
5212 } else { 5200 } else {
5213 return js_object->SetProperty(*name, *value, attr, strict_mode); 5201 Handle<Object> result =
5202 JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
5203 RETURN_IF_EMPTY_HANDLE(isolate, result);
5204 return *result;
5214 } 5205 }
5215 } 5206 }
5216 5207
5217 5208
5218 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate, 5209 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate,
5219 Handle<JSObject> js_object, 5210 Handle<JSObject> js_object,
5220 Handle<Object> key, 5211 Handle<Object> key,
5221 Handle<Object> value, 5212 Handle<Object> value,
5222 PropertyAttributes attr) { 5213 PropertyAttributes attr) {
5223 HandleScope scope(isolate); 5214 HandleScope scope(isolate);
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
5502 ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION; 5493 ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
5503 Handle<Object> result = JSReceiver::DeleteProperty(object, key, delete_mode); 5494 Handle<Object> result = JSReceiver::DeleteProperty(object, key, delete_mode);
5504 RETURN_IF_EMPTY_HANDLE(isolate, result); 5495 RETURN_IF_EMPTY_HANDLE(isolate, result);
5505 return *result; 5496 return *result;
5506 } 5497 }
5507 5498
5508 5499
5509 static MaybeObject* HasLocalPropertyImplementation(Isolate* isolate, 5500 static MaybeObject* HasLocalPropertyImplementation(Isolate* isolate,
5510 Handle<JSObject> object, 5501 Handle<JSObject> object,
5511 Handle<Name> key) { 5502 Handle<Name> key) {
5512 if (object->HasLocalProperty(*key)) return isolate->heap()->true_value(); 5503 if (JSReceiver::HasLocalProperty(object, key)) {
5504 return isolate->heap()->true_value();
5505 }
5513 // Handle hidden prototypes. If there's a hidden prototype above this thing 5506 // Handle hidden prototypes. If there's a hidden prototype above this thing
5514 // then we have to check it for properties, because they are supposed to 5507 // then we have to check it for properties, because they are supposed to
5515 // look like they are on this object. 5508 // look like they are on this object.
5516 Handle<Object> proto(object->GetPrototype(), isolate); 5509 Handle<Object> proto(object->GetPrototype(), isolate);
5517 if (proto->IsJSObject() && 5510 if (proto->IsJSObject() &&
5518 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) { 5511 Handle<JSObject>::cast(proto)->map()->is_hidden_prototype()) {
5519 return HasLocalPropertyImplementation(isolate, 5512 return HasLocalPropertyImplementation(isolate,
5520 Handle<JSObject>::cast(proto), 5513 Handle<JSObject>::cast(proto),
5521 key); 5514 key);
5522 } 5515 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
5562 String* string = String::cast(obj); 5555 String* string = String::cast(obj);
5563 if (index < static_cast<uint32_t>(string->length())) { 5556 if (index < static_cast<uint32_t>(string->length())) {
5564 return isolate->heap()->true_value(); 5557 return isolate->heap()->true_value();
5565 } 5558 }
5566 } 5559 }
5567 return isolate->heap()->false_value(); 5560 return isolate->heap()->false_value();
5568 } 5561 }
5569 5562
5570 5563
5571 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) { 5564 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasProperty) {
5572 SealHandleScope shs(isolate); 5565 HandleScope scope(isolate);
5573 ASSERT(args.length() == 2); 5566 ASSERT(args.length() == 2);
5574 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); 5567 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
5575 CONVERT_ARG_CHECKED(Name, key, 1); 5568 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5576 5569
5577 bool result = receiver->HasProperty(key); 5570 bool result = JSReceiver::HasProperty(receiver, key);
5578 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 5571 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
5579 if (isolate->has_pending_exception()) return Failure::Exception(); 5572 if (isolate->has_pending_exception()) return Failure::Exception();
5580 return isolate->heap()->ToBoolean(result); 5573 return isolate->heap()->ToBoolean(result);
5581 } 5574 }
5582 5575
5583 5576
5584 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) { 5577 RUNTIME_FUNCTION(MaybeObject*, Runtime_HasElement) {
5585 SealHandleScope shs(isolate); 5578 HandleScope scope(isolate);
5586 ASSERT(args.length() == 2); 5579 ASSERT(args.length() == 2);
5587 CONVERT_ARG_CHECKED(JSReceiver, receiver, 0); 5580 CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
5588 CONVERT_SMI_ARG_CHECKED(index, 1); 5581 CONVERT_SMI_ARG_CHECKED(index, 1);
5589 5582
5590 bool result = receiver->HasElement(index); 5583 bool result = JSReceiver::HasElement(receiver, index);
5591 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 5584 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
5592 if (isolate->has_pending_exception()) return Failure::Exception(); 5585 if (isolate->has_pending_exception()) return Failure::Exception();
5593 return isolate->heap()->ToBoolean(result); 5586 return isolate->heap()->ToBoolean(result);
5594 } 5587 }
5595 5588
5596 5589
5597 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) { 5590 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsPropertyEnumerable) {
5598 SealHandleScope shs(isolate); 5591 SealHandleScope shs(isolate);
5599 ASSERT(args.length() == 2); 5592 ASSERT(args.length() == 2);
5600 5593
(...skipping 2898 matching lines...) Expand 10 before | Expand all | Expand 10 after
8499 if (!function->IsOptimizable()) return isolate->heap()->undefined_value(); 8492 if (!function->IsOptimizable()) return isolate->heap()->undefined_value();
8500 function->MarkForLazyRecompilation(); 8493 function->MarkForLazyRecompilation();
8501 8494
8502 Code* unoptimized = function->shared()->code(); 8495 Code* unoptimized = function->shared()->code();
8503 if (args.length() == 2 && 8496 if (args.length() == 2 &&
8504 unoptimized->kind() == Code::FUNCTION) { 8497 unoptimized->kind() == Code::FUNCTION) {
8505 CONVERT_ARG_HANDLE_CHECKED(String, type, 1); 8498 CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
8506 if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) { 8499 if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("osr"))) {
8507 // Start patching from the currently patched loop nesting level. 8500 // Start patching from the currently patched loop nesting level.
8508 int current_level = unoptimized->allow_osr_at_loop_nesting_level(); 8501 int current_level = unoptimized->allow_osr_at_loop_nesting_level();
8509 ASSERT(Deoptimizer::VerifyInterruptCode( 8502 ASSERT(BackEdgeTable::Verify(isolate, unoptimized, current_level));
8510 isolate, unoptimized, current_level));
8511 for (int i = current_level + 1; i <= Code::kMaxLoopNestingMarker; i++) { 8503 for (int i = current_level + 1; i <= Code::kMaxLoopNestingMarker; i++) {
8512 unoptimized->set_allow_osr_at_loop_nesting_level(i); 8504 unoptimized->set_allow_osr_at_loop_nesting_level(i);
8513 isolate->runtime_profiler()->AttemptOnStackReplacement(*function); 8505 isolate->runtime_profiler()->AttemptOnStackReplacement(*function);
8514 } 8506 }
8515 } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("concurrent"))) { 8507 } else if (type->IsOneByteEqualTo(STATIC_ASCII_VECTOR("concurrent"))) {
8516 function->MarkForConcurrentRecompilation(); 8508 function->MarkForConcurrentRecompilation();
8517 } 8509 }
8518 } 8510 }
8519 8511
8520 return isolate->heap()->undefined_value(); 8512 return isolate->heap()->undefined_value();
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
8653 ASSERT(!ast_id.IsNone()); 8645 ASSERT(!ast_id.IsNone());
8654 if (FLAG_trace_osr) { 8646 if (FLAG_trace_osr) {
8655 PrintF("[OSR - replacing at AST id %d in ", ast_id.ToInt()); 8647 PrintF("[OSR - replacing at AST id %d in ", ast_id.ToInt());
8656 function->PrintName(); 8648 function->PrintName();
8657 PrintF("]\n"); 8649 PrintF("]\n");
8658 } 8650 }
8659 // Attempt OSR compilation. 8651 // Attempt OSR compilation.
8660 result = JSFunction::CompileOsr(function, ast_id, CLEAR_EXCEPTION); 8652 result = JSFunction::CompileOsr(function, ast_id, CLEAR_EXCEPTION);
8661 } 8653 }
8662 8654
8663 // Revert the patched interrupt now, regardless of whether OSR succeeds. 8655 // Revert the patched back edge table, regardless of whether OSR succeeds.
8664 Deoptimizer::RevertInterruptCode(isolate, *unoptimized); 8656 BackEdgeTable::Revert(isolate, *unoptimized);
8665 8657
8666 // Check whether we ended up with usable optimized code. 8658 // Check whether we ended up with usable optimized code.
8667 if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) { 8659 if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
8668 DeoptimizationInputData* data = 8660 DeoptimizationInputData* data =
8669 DeoptimizationInputData::cast(result->deoptimization_data()); 8661 DeoptimizationInputData::cast(result->deoptimization_data());
8670 8662
8671 if (data->OsrPcOffset()->value() >= 0) { 8663 if (data->OsrPcOffset()->value() >= 0) {
8672 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id); 8664 ASSERT(BailoutId(data->OsrAstId()->value()) == ast_id);
8673 if (FLAG_trace_osr) { 8665 if (FLAG_trace_osr) {
8674 PrintF("[OSR - entry at AST id %d, offset %d in optimized code]\n", 8666 PrintF("[OSR - entry at AST id %d, offset %d in optimized code]\n",
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
9191 UNREACHABLE(); 9183 UNREACHABLE();
9192 return MakePair(NULL, NULL); 9184 return MakePair(NULL, NULL);
9193 } 9185 }
9194 } 9186 }
9195 9187
9196 // Otherwise, if the slot was found the holder is a context extension 9188 // Otherwise, if the slot was found the holder is a context extension
9197 // object, subject of a with, or a global object. We read the named 9189 // object, subject of a with, or a global object. We read the named
9198 // property from it. 9190 // property from it.
9199 if (!holder.is_null()) { 9191 if (!holder.is_null()) {
9200 Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder); 9192 Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
9201 ASSERT(object->IsJSProxy() || object->HasProperty(*name)); 9193 ASSERT(object->IsJSProxy() || JSReceiver::HasProperty(object, name));
9202 // GetProperty below can cause GC. 9194 // GetProperty below can cause GC.
9203 Handle<Object> receiver_handle( 9195 Handle<Object> receiver_handle(
9204 object->IsGlobalObject() 9196 object->IsGlobalObject()
9205 ? GlobalObject::cast(*object)->global_receiver() 9197 ? GlobalObject::cast(*object)->global_receiver()
9206 : object->IsJSProxy() ? static_cast<Object*>(*object) 9198 : object->IsJSProxy() ? static_cast<Object*>(*object)
9207 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)), 9199 : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)),
9208 isolate); 9200 isolate);
9209 9201
9210 // No need to unhole the value here. This is taken care of by the 9202 // No need to unhole the value here. This is taken care of by the
9211 // GetProperty function. 9203 // GetProperty function.
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after
10172 // Run through the elements FixedArray and use HasElement and GetElement 10164 // Run through the elements FixedArray and use HasElement and GetElement
10173 // to check the prototype for missing elements. 10165 // to check the prototype for missing elements.
10174 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); 10166 Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
10175 int fast_length = static_cast<int>(length); 10167 int fast_length = static_cast<int>(length);
10176 ASSERT(fast_length <= elements->length()); 10168 ASSERT(fast_length <= elements->length());
10177 for (int j = 0; j < fast_length; j++) { 10169 for (int j = 0; j < fast_length; j++) {
10178 HandleScope loop_scope(isolate); 10170 HandleScope loop_scope(isolate);
10179 Handle<Object> element_value(elements->get(j), isolate); 10171 Handle<Object> element_value(elements->get(j), isolate);
10180 if (!element_value->IsTheHole()) { 10172 if (!element_value->IsTheHole()) {
10181 visitor->visit(j, element_value); 10173 visitor->visit(j, element_value);
10182 } else if (receiver->HasElement(j)) { 10174 } else if (JSReceiver::HasElement(receiver, j)) {
10183 // Call GetElement on receiver, not its prototype, or getters won't 10175 // Call GetElement on receiver, not its prototype, or getters won't
10184 // have the correct receiver. 10176 // have the correct receiver.
10185 element_value = Object::GetElement(isolate, receiver, j); 10177 element_value = Object::GetElement(isolate, receiver, j);
10186 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); 10178 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
10187 visitor->visit(j, element_value); 10179 visitor->visit(j, element_value);
10188 } 10180 }
10189 } 10181 }
10190 break; 10182 break;
10191 } 10183 }
10192 case FAST_HOLEY_DOUBLE_ELEMENTS: 10184 case FAST_HOLEY_DOUBLE_ELEMENTS:
10193 case FAST_DOUBLE_ELEMENTS: { 10185 case FAST_DOUBLE_ELEMENTS: {
10194 // Run through the elements FixedArray and use HasElement and GetElement 10186 // Run through the elements FixedArray and use HasElement and GetElement
10195 // to check the prototype for missing elements. 10187 // to check the prototype for missing elements.
10196 Handle<FixedDoubleArray> elements( 10188 Handle<FixedDoubleArray> elements(
10197 FixedDoubleArray::cast(receiver->elements())); 10189 FixedDoubleArray::cast(receiver->elements()));
10198 int fast_length = static_cast<int>(length); 10190 int fast_length = static_cast<int>(length);
10199 ASSERT(fast_length <= elements->length()); 10191 ASSERT(fast_length <= elements->length());
10200 for (int j = 0; j < fast_length; j++) { 10192 for (int j = 0; j < fast_length; j++) {
10201 HandleScope loop_scope(isolate); 10193 HandleScope loop_scope(isolate);
10202 if (!elements->is_the_hole(j)) { 10194 if (!elements->is_the_hole(j)) {
10203 double double_value = elements->get_scalar(j); 10195 double double_value = elements->get_scalar(j);
10204 Handle<Object> element_value = 10196 Handle<Object> element_value =
10205 isolate->factory()->NewNumber(double_value); 10197 isolate->factory()->NewNumber(double_value);
10206 visitor->visit(j, element_value); 10198 visitor->visit(j, element_value);
10207 } else if (receiver->HasElement(j)) { 10199 } else if (JSReceiver::HasElement(receiver, j)) {
10208 // Call GetElement on receiver, not its prototype, or getters won't 10200 // Call GetElement on receiver, not its prototype, or getters won't
10209 // have the correct receiver. 10201 // have the correct receiver.
10210 Handle<Object> element_value = 10202 Handle<Object> element_value =
10211 Object::GetElement(isolate, receiver, j); 10203 Object::GetElement(isolate, receiver, j);
10212 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); 10204 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
10213 visitor->visit(j, element_value); 10205 visitor->visit(j, element_value);
10214 } 10206 }
10215 } 10207 }
10216 break; 10208 break;
10217 } 10209 }
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after
11513 isolate, scope_info, function_context, variable_name, new_value)) { 11505 isolate, scope_info, function_context, variable_name, new_value)) {
11514 return true; 11506 return true;
11515 } 11507 }
11516 11508
11517 // Function context extension. These are variables introduced by eval. 11509 // Function context extension. These are variables introduced by eval.
11518 if (function_context->closure() == *function) { 11510 if (function_context->closure() == *function) {
11519 if (function_context->has_extension() && 11511 if (function_context->has_extension() &&
11520 !function_context->IsNativeContext()) { 11512 !function_context->IsNativeContext()) {
11521 Handle<JSObject> ext(JSObject::cast(function_context->extension())); 11513 Handle<JSObject> ext(JSObject::cast(function_context->extension()));
11522 11514
11523 if (ext->HasProperty(*variable_name)) { 11515 if (JSReceiver::HasProperty(ext, variable_name)) {
11524 // We don't expect this to do anything except replacing 11516 // We don't expect this to do anything except replacing
11525 // property value. 11517 // property value.
11526 SetProperty(isolate, 11518 SetProperty(isolate,
11527 ext, 11519 ext,
11528 variable_name, 11520 variable_name,
11529 new_value, 11521 new_value,
11530 NONE, 11522 NONE,
11531 kNonStrictMode); 11523 kNonStrictMode);
11532 return true; 11524 return true;
11533 } 11525 }
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
11601 // Context locals to the context extension. 11593 // Context locals to the context extension.
11602 if (SetContextLocalValue( 11594 if (SetContextLocalValue(
11603 isolate, scope_info, context, variable_name, new_value)) { 11595 isolate, scope_info, context, variable_name, new_value)) {
11604 return true; 11596 return true;
11605 } 11597 }
11606 11598
11607 // Properties from the function context extension. This will 11599 // Properties from the function context extension. This will
11608 // be variables introduced by eval. 11600 // be variables introduced by eval.
11609 if (context->has_extension()) { 11601 if (context->has_extension()) {
11610 Handle<JSObject> ext(JSObject::cast(context->extension())); 11602 Handle<JSObject> ext(JSObject::cast(context->extension()));
11611 if (ext->HasProperty(*variable_name)) { 11603 if (JSReceiver::HasProperty(ext, variable_name)) {
11612 // We don't expect this to do anything except replacing property value. 11604 // We don't expect this to do anything except replacing property value.
11613 SetProperty(isolate, 11605 SetProperty(isolate,
11614 ext, 11606 ext,
11615 variable_name, 11607 variable_name,
11616 new_value, 11608 new_value,
11617 NONE, 11609 NONE,
11618 kNonStrictMode); 11610 kNonStrictMode);
11619 return true; 11611 return true;
11620 } 11612 }
11621 } 11613 }
(...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after
12644 12636
12645 // Helper function to find or create the arguments object for 12637 // Helper function to find or create the arguments object for
12646 // Runtime_DebugEvaluate. 12638 // Runtime_DebugEvaluate.
12647 static Handle<JSObject> MaterializeArgumentsObject( 12639 static Handle<JSObject> MaterializeArgumentsObject(
12648 Isolate* isolate, 12640 Isolate* isolate,
12649 Handle<JSObject> target, 12641 Handle<JSObject> target,
12650 Handle<JSFunction> function) { 12642 Handle<JSFunction> function) {
12651 // Do not materialize the arguments object for eval or top-level code. 12643 // Do not materialize the arguments object for eval or top-level code.
12652 // Skip if "arguments" is already taken. 12644 // Skip if "arguments" is already taken.
12653 if (!function->shared()->is_function() || 12645 if (!function->shared()->is_function() ||
12654 target->HasLocalProperty(isolate->heap()->arguments_string())) { 12646 JSReceiver::HasLocalProperty(target,
12647 isolate->factory()->arguments_string())) {
12655 return target; 12648 return target;
12656 } 12649 }
12657 12650
12658 // FunctionGetArguments can't throw an exception. 12651 // FunctionGetArguments can't throw an exception.
12659 Handle<JSObject> arguments = Handle<JSObject>::cast( 12652 Handle<JSObject> arguments = Handle<JSObject>::cast(
12660 Accessors::FunctionGetArguments(function)); 12653 Accessors::FunctionGetArguments(function));
12661 SetProperty(isolate, 12654 SetProperty(isolate,
12662 target, 12655 target,
12663 isolate->factory()->arguments_string(), 12656 isolate->factory()->arguments_string(),
12664 arguments, 12657 arguments,
(...skipping 2141 matching lines...) Expand 10 before | Expand all | Expand 10 after
14806 // Handle last resort GC and make sure to allow future allocations 14799 // Handle last resort GC and make sure to allow future allocations
14807 // to grow the heap without causing GCs (if possible). 14800 // to grow the heap without causing GCs (if possible).
14808 isolate->counters()->gc_last_resort_from_js()->Increment(); 14801 isolate->counters()->gc_last_resort_from_js()->Increment();
14809 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 14802 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
14810 "Runtime::PerformGC"); 14803 "Runtime::PerformGC");
14811 } 14804 }
14812 } 14805 }
14813 14806
14814 14807
14815 } } // namespace v8::internal 14808 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/runtime-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698