| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 #include "src/keys.h" | 50 #include "src/keys.h" |
| 51 #include "src/list.h" | 51 #include "src/list.h" |
| 52 #include "src/log.h" | 52 #include "src/log.h" |
| 53 #include "src/lookup.h" | 53 #include "src/lookup.h" |
| 54 #include "src/macro-assembler.h" | 54 #include "src/macro-assembler.h" |
| 55 #include "src/map-updater.h" | 55 #include "src/map-updater.h" |
| 56 #include "src/messages.h" | 56 #include "src/messages.h" |
| 57 #include "src/objects-body-descriptors-inl.h" | 57 #include "src/objects-body-descriptors-inl.h" |
| 58 #include "src/objects/code-cache-inl.h" | 58 #include "src/objects/code-cache-inl.h" |
| 59 #include "src/objects/compilation-cache-inl.h" | 59 #include "src/objects/compilation-cache-inl.h" |
| 60 #include "src/objects/debug-objects-inl.h" |
| 60 #include "src/objects/frame-array-inl.h" | 61 #include "src/objects/frame-array-inl.h" |
| 61 #include "src/objects/map.h" | 62 #include "src/objects/map.h" |
| 62 #include "src/property-descriptor.h" | 63 #include "src/property-descriptor.h" |
| 63 #include "src/prototype.h" | 64 #include "src/prototype.h" |
| 64 #include "src/regexp/jsregexp.h" | 65 #include "src/regexp/jsregexp.h" |
| 65 #include "src/safepoint-table.h" | 66 #include "src/safepoint-table.h" |
| 66 #include "src/snapshot/code-serializer.h" | 67 #include "src/snapshot/code-serializer.h" |
| 67 #include "src/source-position-table.h" | 68 #include "src/source-position-table.h" |
| 68 #include "src/string-builder.h" | 69 #include "src/string-builder.h" |
| 69 #include "src/string-search.h" | 70 #include "src/string-search.h" |
| (...skipping 13336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13406 } else { | 13407 } else { |
| 13407 // Remove shared function info from root array. | 13408 // Remove shared function info from root array. |
| 13408 Object* list = isolate->heap()->noscript_shared_function_infos(); | 13409 Object* list = isolate->heap()->noscript_shared_function_infos(); |
| 13409 CHECK(WeakFixedArray::cast(list)->Remove(shared)); | 13410 CHECK(WeakFixedArray::cast(list)->Remove(shared)); |
| 13410 } | 13411 } |
| 13411 | 13412 |
| 13412 // Finally set new script. | 13413 // Finally set new script. |
| 13413 shared->set_script(*script_object); | 13414 shared->set_script(*script_object); |
| 13414 } | 13415 } |
| 13415 | 13416 |
| 13417 DebugInfo* SharedFunctionInfo::GetDebugInfo() const { |
| 13418 DCHECK(HasDebugInfo()); |
| 13419 return DebugInfo::cast(debug_info()); |
| 13420 } |
| 13421 |
| 13422 int SharedFunctionInfo::debugger_hints() const { |
| 13423 if (HasDebugInfo()) return GetDebugInfo()->debugger_hints(); |
| 13424 return Smi::cast(debug_info())->value(); |
| 13425 } |
| 13426 |
| 13427 void SharedFunctionInfo::set_debugger_hints(int value) { |
| 13428 if (HasDebugInfo()) { |
| 13429 GetDebugInfo()->set_debugger_hints(value); |
| 13430 } else { |
| 13431 set_debug_info(Smi::FromInt(value)); |
| 13432 } |
| 13433 } |
| 13416 | 13434 |
| 13417 String* SharedFunctionInfo::DebugName() { | 13435 String* SharedFunctionInfo::DebugName() { |
| 13418 Object* n = name(); | 13436 Object* n = name(); |
| 13419 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); | 13437 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); |
| 13420 return String::cast(n); | 13438 return String::cast(n); |
| 13421 } | 13439 } |
| 13422 | 13440 |
| 13423 bool SharedFunctionInfo::HasNoSideEffect() { | 13441 bool SharedFunctionInfo::HasNoSideEffect() { |
| 13424 if (!computed_has_no_side_effect()) { | 13442 if (!computed_has_no_side_effect()) { |
| 13425 DisallowHeapAllocation not_handlified; | 13443 DisallowHeapAllocation not_handlified; |
| (...skipping 5681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19107 Object* value = table->Lookup(key); | 19125 Object* value = table->Lookup(key); |
| 19108 entries->set(count++, value); | 19126 entries->set(count++, value); |
| 19109 } | 19127 } |
| 19110 } | 19128 } |
| 19111 } | 19129 } |
| 19112 DCHECK_EQ(max_entries * values_per_entry, count); | 19130 DCHECK_EQ(max_entries * values_per_entry, count); |
| 19113 } | 19131 } |
| 19114 return isolate->factory()->NewJSArrayWithElements(entries); | 19132 return isolate->factory()->NewJSArrayWithElements(entries); |
| 19115 } | 19133 } |
| 19116 | 19134 |
| 19117 // Check if there is a break point at this source position. | |
| 19118 bool DebugInfo::HasBreakPoint(int source_position) { | |
| 19119 // Get the break point info object for this code offset. | |
| 19120 Object* break_point_info = GetBreakPointInfo(source_position); | |
| 19121 | |
| 19122 // If there is no break point info object or no break points in the break | |
| 19123 // point info object there is no break point at this code offset. | |
| 19124 if (break_point_info->IsUndefined(GetIsolate())) return false; | |
| 19125 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; | |
| 19126 } | |
| 19127 | |
| 19128 // Get the break point info object for this source position. | |
| 19129 Object* DebugInfo::GetBreakPointInfo(int source_position) { | |
| 19130 Isolate* isolate = GetIsolate(); | |
| 19131 if (!break_points()->IsUndefined(isolate)) { | |
| 19132 for (int i = 0; i < break_points()->length(); i++) { | |
| 19133 if (!break_points()->get(i)->IsUndefined(isolate)) { | |
| 19134 BreakPointInfo* break_point_info = | |
| 19135 BreakPointInfo::cast(break_points()->get(i)); | |
| 19136 if (break_point_info->source_position() == source_position) { | |
| 19137 return break_point_info; | |
| 19138 } | |
| 19139 } | |
| 19140 } | |
| 19141 } | |
| 19142 return isolate->heap()->undefined_value(); | |
| 19143 } | |
| 19144 | |
| 19145 bool DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, | |
| 19146 Handle<Object> break_point_object) { | |
| 19147 Isolate* isolate = debug_info->GetIsolate(); | |
| 19148 if (debug_info->break_points()->IsUndefined(isolate)) return false; | |
| 19149 | |
| 19150 for (int i = 0; i < debug_info->break_points()->length(); i++) { | |
| 19151 if (debug_info->break_points()->get(i)->IsUndefined(isolate)) continue; | |
| 19152 Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>( | |
| 19153 BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate); | |
| 19154 if (BreakPointInfo::HasBreakPointObject(break_point_info, | |
| 19155 break_point_object)) { | |
| 19156 BreakPointInfo::ClearBreakPoint(break_point_info, break_point_object); | |
| 19157 return true; | |
| 19158 } | |
| 19159 } | |
| 19160 return false; | |
| 19161 } | |
| 19162 | |
| 19163 void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int source_position, | |
| 19164 Handle<Object> break_point_object) { | |
| 19165 Isolate* isolate = debug_info->GetIsolate(); | |
| 19166 Handle<Object> break_point_info( | |
| 19167 debug_info->GetBreakPointInfo(source_position), isolate); | |
| 19168 if (!break_point_info->IsUndefined(isolate)) { | |
| 19169 BreakPointInfo::SetBreakPoint( | |
| 19170 Handle<BreakPointInfo>::cast(break_point_info), | |
| 19171 break_point_object); | |
| 19172 return; | |
| 19173 } | |
| 19174 | |
| 19175 // Adding a new break point for a code offset which did not have any | |
| 19176 // break points before. Try to find a free slot. | |
| 19177 static const int kNoBreakPointInfo = -1; | |
| 19178 int index = kNoBreakPointInfo; | |
| 19179 for (int i = 0; i < debug_info->break_points()->length(); i++) { | |
| 19180 if (debug_info->break_points()->get(i)->IsUndefined(isolate)) { | |
| 19181 index = i; | |
| 19182 break; | |
| 19183 } | |
| 19184 } | |
| 19185 if (index == kNoBreakPointInfo) { | |
| 19186 // No free slot - extend break point info array. | |
| 19187 Handle<FixedArray> old_break_points = Handle<FixedArray>( | |
| 19188 FixedArray::cast(debug_info->break_points()), isolate); | |
| 19189 Handle<FixedArray> new_break_points = | |
| 19190 isolate->factory()->NewFixedArray( | |
| 19191 old_break_points->length() + | |
| 19192 DebugInfo::kEstimatedNofBreakPointsInFunction); | |
| 19193 | |
| 19194 debug_info->set_break_points(*new_break_points); | |
| 19195 for (int i = 0; i < old_break_points->length(); i++) { | |
| 19196 new_break_points->set(i, old_break_points->get(i)); | |
| 19197 } | |
| 19198 index = old_break_points->length(); | |
| 19199 } | |
| 19200 DCHECK(index != kNoBreakPointInfo); | |
| 19201 | |
| 19202 // Allocate new BreakPointInfo object and set the break point. | |
| 19203 Handle<BreakPointInfo> new_break_point_info = | |
| 19204 isolate->factory()->NewBreakPointInfo(source_position); | |
| 19205 BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object); | |
| 19206 debug_info->break_points()->set(index, *new_break_point_info); | |
| 19207 } | |
| 19208 | |
| 19209 // Get the break point objects for a source position. | |
| 19210 Handle<Object> DebugInfo::GetBreakPointObjects(int source_position) { | |
| 19211 Object* break_point_info = GetBreakPointInfo(source_position); | |
| 19212 Isolate* isolate = GetIsolate(); | |
| 19213 if (break_point_info->IsUndefined(isolate)) { | |
| 19214 return isolate->factory()->undefined_value(); | |
| 19215 } | |
| 19216 return Handle<Object>( | |
| 19217 BreakPointInfo::cast(break_point_info)->break_point_objects(), isolate); | |
| 19218 } | |
| 19219 | |
| 19220 | |
| 19221 // Get the total number of break points. | |
| 19222 int DebugInfo::GetBreakPointCount() { | |
| 19223 Isolate* isolate = GetIsolate(); | |
| 19224 if (break_points()->IsUndefined(isolate)) return 0; | |
| 19225 int count = 0; | |
| 19226 for (int i = 0; i < break_points()->length(); i++) { | |
| 19227 if (!break_points()->get(i)->IsUndefined(isolate)) { | |
| 19228 BreakPointInfo* break_point_info = | |
| 19229 BreakPointInfo::cast(break_points()->get(i)); | |
| 19230 count += break_point_info->GetBreakPointCount(); | |
| 19231 } | |
| 19232 } | |
| 19233 return count; | |
| 19234 } | |
| 19235 | |
| 19236 | |
| 19237 Handle<Object> DebugInfo::FindBreakPointInfo( | |
| 19238 Handle<DebugInfo> debug_info, Handle<Object> break_point_object) { | |
| 19239 Isolate* isolate = debug_info->GetIsolate(); | |
| 19240 if (!debug_info->break_points()->IsUndefined(isolate)) { | |
| 19241 for (int i = 0; i < debug_info->break_points()->length(); i++) { | |
| 19242 if (!debug_info->break_points()->get(i)->IsUndefined(isolate)) { | |
| 19243 Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>( | |
| 19244 BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate); | |
| 19245 if (BreakPointInfo::HasBreakPointObject(break_point_info, | |
| 19246 break_point_object)) { | |
| 19247 return break_point_info; | |
| 19248 } | |
| 19249 } | |
| 19250 } | |
| 19251 } | |
| 19252 return isolate->factory()->undefined_value(); | |
| 19253 } | |
| 19254 | |
| 19255 // Remove the specified break point object. | |
| 19256 void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info, | |
| 19257 Handle<Object> break_point_object) { | |
| 19258 Isolate* isolate = break_point_info->GetIsolate(); | |
| 19259 // If there are no break points just ignore. | |
| 19260 if (break_point_info->break_point_objects()->IsUndefined(isolate)) return; | |
| 19261 // If there is a single break point clear it if it is the same. | |
| 19262 if (!break_point_info->break_point_objects()->IsFixedArray()) { | |
| 19263 if (break_point_info->break_point_objects() == *break_point_object) { | |
| 19264 break_point_info->set_break_point_objects( | |
| 19265 isolate->heap()->undefined_value()); | |
| 19266 } | |
| 19267 return; | |
| 19268 } | |
| 19269 // If there are multiple break points shrink the array | |
| 19270 DCHECK(break_point_info->break_point_objects()->IsFixedArray()); | |
| 19271 Handle<FixedArray> old_array = | |
| 19272 Handle<FixedArray>( | |
| 19273 FixedArray::cast(break_point_info->break_point_objects())); | |
| 19274 Handle<FixedArray> new_array = | |
| 19275 isolate->factory()->NewFixedArray(old_array->length() - 1); | |
| 19276 int found_count = 0; | |
| 19277 for (int i = 0; i < old_array->length(); i++) { | |
| 19278 if (old_array->get(i) == *break_point_object) { | |
| 19279 DCHECK(found_count == 0); | |
| 19280 found_count++; | |
| 19281 } else { | |
| 19282 new_array->set(i - found_count, old_array->get(i)); | |
| 19283 } | |
| 19284 } | |
| 19285 // If the break point was found in the list change it. | |
| 19286 if (found_count > 0) break_point_info->set_break_point_objects(*new_array); | |
| 19287 } | |
| 19288 | |
| 19289 | |
| 19290 // Add the specified break point object. | |
| 19291 void BreakPointInfo::SetBreakPoint(Handle<BreakPointInfo> break_point_info, | |
| 19292 Handle<Object> break_point_object) { | |
| 19293 Isolate* isolate = break_point_info->GetIsolate(); | |
| 19294 | |
| 19295 // If there was no break point objects before just set it. | |
| 19296 if (break_point_info->break_point_objects()->IsUndefined(isolate)) { | |
| 19297 break_point_info->set_break_point_objects(*break_point_object); | |
| 19298 return; | |
| 19299 } | |
| 19300 // If the break point object is the same as before just ignore. | |
| 19301 if (break_point_info->break_point_objects() == *break_point_object) return; | |
| 19302 // If there was one break point object before replace with array. | |
| 19303 if (!break_point_info->break_point_objects()->IsFixedArray()) { | |
| 19304 Handle<FixedArray> array = isolate->factory()->NewFixedArray(2); | |
| 19305 array->set(0, break_point_info->break_point_objects()); | |
| 19306 array->set(1, *break_point_object); | |
| 19307 break_point_info->set_break_point_objects(*array); | |
| 19308 return; | |
| 19309 } | |
| 19310 // If there was more than one break point before extend array. | |
| 19311 Handle<FixedArray> old_array = | |
| 19312 Handle<FixedArray>( | |
| 19313 FixedArray::cast(break_point_info->break_point_objects())); | |
| 19314 Handle<FixedArray> new_array = | |
| 19315 isolate->factory()->NewFixedArray(old_array->length() + 1); | |
| 19316 for (int i = 0; i < old_array->length(); i++) { | |
| 19317 // If the break point was there before just ignore. | |
| 19318 if (old_array->get(i) == *break_point_object) return; | |
| 19319 new_array->set(i, old_array->get(i)); | |
| 19320 } | |
| 19321 // Add the new break point. | |
| 19322 new_array->set(old_array->length(), *break_point_object); | |
| 19323 break_point_info->set_break_point_objects(*new_array); | |
| 19324 } | |
| 19325 | |
| 19326 | |
| 19327 bool BreakPointInfo::HasBreakPointObject( | |
| 19328 Handle<BreakPointInfo> break_point_info, | |
| 19329 Handle<Object> break_point_object) { | |
| 19330 // No break point. | |
| 19331 Isolate* isolate = break_point_info->GetIsolate(); | |
| 19332 if (break_point_info->break_point_objects()->IsUndefined(isolate)) { | |
| 19333 return false; | |
| 19334 } | |
| 19335 // Single break point. | |
| 19336 if (!break_point_info->break_point_objects()->IsFixedArray()) { | |
| 19337 return break_point_info->break_point_objects() == *break_point_object; | |
| 19338 } | |
| 19339 // Multiple break points. | |
| 19340 FixedArray* array = FixedArray::cast(break_point_info->break_point_objects()); | |
| 19341 for (int i = 0; i < array->length(); i++) { | |
| 19342 if (array->get(i) == *break_point_object) { | |
| 19343 return true; | |
| 19344 } | |
| 19345 } | |
| 19346 return false; | |
| 19347 } | |
| 19348 | |
| 19349 | |
| 19350 // Get the number of break points. | |
| 19351 int BreakPointInfo::GetBreakPointCount() { | |
| 19352 // No break point. | |
| 19353 if (break_point_objects()->IsUndefined(GetIsolate())) return 0; | |
| 19354 // Single break point. | |
| 19355 if (!break_point_objects()->IsFixedArray()) return 1; | |
| 19356 // Multiple break points. | |
| 19357 return FixedArray::cast(break_point_objects())->length(); | |
| 19358 } | |
| 19359 | |
| 19360 | |
| 19361 // static | 19135 // static |
| 19362 MaybeHandle<JSDate> JSDate::New(Handle<JSFunction> constructor, | 19136 MaybeHandle<JSDate> JSDate::New(Handle<JSFunction> constructor, |
| 19363 Handle<JSReceiver> new_target, double tv) { | 19137 Handle<JSReceiver> new_target, double tv) { |
| 19364 Isolate* const isolate = constructor->GetIsolate(); | 19138 Isolate* const isolate = constructor->GetIsolate(); |
| 19365 Handle<JSObject> result; | 19139 Handle<JSObject> result; |
| 19366 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, | 19140 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, |
| 19367 JSObject::New(constructor, new_target), JSDate); | 19141 JSObject::New(constructor, new_target), JSDate); |
| 19368 if (-DateCache::kMaxTimeInMs <= tv && tv <= DateCache::kMaxTimeInMs) { | 19142 if (-DateCache::kMaxTimeInMs <= tv && tv <= DateCache::kMaxTimeInMs) { |
| 19369 tv = DoubleToInteger(tv) + 0.0; | 19143 tv = DoubleToInteger(tv) + 0.0; |
| 19370 } else { | 19144 } else { |
| (...skipping 1250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20621 // not | 20395 // not |
| 20622 // depend on this. | 20396 // depend on this. |
| 20623 return DICTIONARY_ELEMENTS; | 20397 return DICTIONARY_ELEMENTS; |
| 20624 } | 20398 } |
| 20625 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 20399 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
| 20626 return kind; | 20400 return kind; |
| 20627 } | 20401 } |
| 20628 } | 20402 } |
| 20629 } // namespace internal | 20403 } // namespace internal |
| 20630 } // namespace v8 | 20404 } // namespace v8 |
| OLD | NEW |